home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics 16,000
/
graphics-16000.iso
/
msdos
/
fractal
/
fdesi313
/
fdes13s
/
fdestria.c
< prev
next >
Wrap
Text File
|
1990-01-23
|
7KB
|
239 lines
/*
Triangle operations
*/
#include <graphics.h>
#include <float.h>
#include <math.h>
typedef struct {
float row[3];
float col[3];
} triangle;
#include "fdesign.h"
#include "fdesequa.h"
#include "fdesfile.h"
#include "fdesmenu.h"
#include "fdesmous.h"
#include "fdesplot.h"
/* ****************************************************************** */
int triangle_new(triangle *t,int tcolor) /* input triangle coordinates from mouse */
{
int rcode;
mouse_state m;
rcode = mouse_click_grat(&m); /* point 1 of triangle */
if (rcode&0x02) return(rcode);
setcolor(tcolor);
(*t).row[0] = m.row;
(*t).col[0] = m.col;
outtextxy(m.col,m.row,"A");
mouse_click_grat(&m); /* point 2 of triangle */
(*t).row[1] = m.row;
setcolor(tcolor);
outtextxy(m.col,m.row,"B");
(*t).col[1] = m.col;
line((*t).col[0],(*t).row[0],(*t).col[1],(*t).row[1]);
rcode = mouse_click_grat(&m); /* point 3 of triangle */
setcolor(tcolor);
(*t).row[2] = m.row;
(*t).col[2] = m.col;
outtextxy(m.col,m.row,"C");
line((*t).col[1],(*t).row[1],(*t).col[2],(*t).row[2]);
line((*t).col[2],(*t).row[2],(*t).col[0],(*t).row[0]);
return(rcode);
}
void triangle_show(triangle *t)
{
line((*t).col[0],(*t).row[0],(*t).col[1],(*t).row[1]);
outtextxy((*t).col[0],(*t).row[0],"A");
line((*t).col[1],(*t).row[1],(*t).col[2],(*t).row[2]);
outtextxy((*t).col[1],(*t).row[1],"B");
line((*t).col[2],(*t).row[2],(*t).col[0],(*t).row[0]);
outtextxy((*t).col[2],(*t).row[2],"C");
}
/*
Distance of a point to a point
*/
float pt_pt_distance(float x1, float y1, float x2, float y2)
{
float d2;
d2 = (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2);
if (d2 == 0.0) return (0.0);
else return (sqrt(d2));
}
/*
Return closest triangle corner ( 0 1 or 2 )
*/
int triangle_corner(triangle *t, float col, float row)
{
float a,b,c;
a = pt_pt_distance((*t).row[0],(*t).col[0],row,col);
b = pt_pt_distance((*t).row[1],(*t).col[1],row,col);
c = pt_pt_distance((*t).row[2],(*t).col[2],row,col);
if ((a<b)&&(a<c)) return(0);
if (b<c) return(1);
else return(2);
}
/*
Distance of a point to a line
*/
float pt_line_distance(float x, float y, float x1, float y1, float x2, float y2)
{
float a,b,e,c;
if ((x==x1) && (y==y1)) a = 0.0;
else a = sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1));
if ((x==x2) && (y==y2)) b = 0.0;
else b = sqrt((x-x2)*(x-x2)+(y-y2)*(y-y2));
if ((x1==x2) && (y1==y2)) e = 0.0;
else e = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
if (e != 0.0)
{
c = (b*b - a*a - e*e)/(-2*e);
if ((a*a-c*c) < 0.0) return(0.0);
else return(sqrt(a*a-c*c));
}
else
return(a);
}
/*
Distance of a point to a line SEGMENT
(to locate nearest triangle edge)
*/
float pt_lines_distance(float x, float y, float x1, float y1, float x2, float y2)
{
float a,b,e,c;
if ((x==x1) && (y==y1)) a = 0.0;
else a = sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1));
if ((x==x2) && (y==y2)) b = 0.0;
else b = sqrt((x-x2)*(x-x2)+(y-y2)*(y-y2));
if ((x1==x2) && (y1==y2)) e = 0.0;
else e = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
if ((a*a + e*e) < (b*b)) return(a);
if ((b*b + e*e) < (a*a)) return(b);
if (e != 0.0)
{
c = (b*b - a*a - e*e)/(-2*e);
if ((a*a-c*c) < 0.0) return(0.0);
else return(sqrt(a*a-c*c));
}
else
return(a);
}
float pt_triangle_distance(float x, float y, triangle *t)
{
float n1,n2,n3;
n1 = pt_lines_distance(x,y,(*t).col[0],(*t).row[0],(*t).col[1],(*t).row[1]);
n2 = pt_lines_distance(x,y,(*t).col[1],(*t).row[1],(*t).col[2],(*t).row[2]);
n3 = pt_lines_distance(x,y,(*t).col[2],(*t).row[2],(*t).col[0],(*t).row[0]);
if (n2 < n1) n1 = n2;
if (n3 < n1) n1 = n3;
return(n1);
}
/*
Finds the triangle closest to the point specified.
Returns the triangle number or -1 if the reference triangle.
*/
int pt_closest_triangle(float x, float y)
{
float dist[MAXFUNC];
float dist_ref;
int i;
int best_t;
dist_ref = pt_triangle_distance(x,y,&triangle0);
/* gotoxy(1,12); printf("%6f",dist_ref);
*/ for (i=0; i<num_triangles; i++)
{
dist[i] = pt_triangle_distance(x,y,&triangles[i]);
/* printf(" %6f",dist[i]);
*/ }
/* find minimum */
best_t = 0;
for (i=(num_triangles - 1); i>0; i--)
{
if (dist[i] < dist[0])
{
dist[0] = dist[i];
best_t = i;
}
}
if (dist_ref < dist[0]) return(-1);
else return(best_t);
}
/*
Find triangle area.
Collapsed triangles (base or height = 0) will have an area assuming
one pixel width (instead of zero).
*/
float triangle_area(triangle *t)
{
float base,height;
/* area is 1/2 base times height */
base = pt_pt_distance((*t).col[0],(*t).row[0],(*t).col[1],(*t).row[1]);
height = pt_line_distance((*t).col[2],(*t).row[2],(*t).col[1],(*t).row[1],
(*t).col[0],(*t).row[0]);
if (base < 1.0) return(5.0*height); /* && 3.0 was 1.0 */
else if (height < 1.0) return(5.0*base); /* && 3.0 was 1.0 */
else return(0.5*base*height);
}
/************************************************************************
Transformation Check if affine
************************************************************************/
int transform_affine(triangle *t) /* return 0 if not affine */
{
float ra,rb,rc;
float a,b,c;
ra = pt_pt_distance(triangle0.row[0],triangle0.col[0],
triangle0.row[1],triangle0.col[1]);
rb = pt_pt_distance(triangle0.row[1],triangle0.col[1],
triangle0.row[2],triangle0.col[2]);
rc = pt_pt_distance(triangle0.row[2],triangle0.col[2],
triangle0.row[0],triangle0.col[0]);
a = pt_pt_distance((*t).row[0],(*t).col[0],(*t).row[1],(*t).col[1]);
b = pt_pt_distance((*t).row[1],(*t).col[1],(*t).row[2],(*t).col[2]);
c = pt_pt_distance((*t).row[2],(*t).col[2],(*t).row[0],(*t).col[0]);
if (a > ra) return(0);
if (b > rb) return(0);
if (c > rc) return(0);
if ((a == ra) && (b == rb) && (c == rc)) return(0);
return(1);
}
/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Find screen limits of Triangles
(used to re-orient Triangles on screen)
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
void triangles_limits(float *left,float *up,float *right,float *down)
{
int i,j;
*left = *right = triangle0.col[0];
*up = *down = triangle0.row[0];
for (i=0; i<3; i++)
{
if (triangle0.row[i] < *up) *up = triangle0.row[i];
if (triangle0.row[i] > *down) *down = triangle0.row[i];
if (triangle0.col[i] < *left) *left = triangle0.col[i];
if (triangle0.col[i] > *right) *right = triangle0.col[i];
}
for (j=0; j<num_triangles; j++)
{
for (i=0; i<3; i++)
{
if (triangles[j].row[i] < *up) *up = triangles[j].row[i];
if (triangles[j].row[i] > *down) *down = triangles[j].row[i];
if (triangles[j].col[i] < *left) *left = triangles[j].col[i];
if (triangles[j].col[i] > *right) *right = triangles[j].col[i];
}
}
}