00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "neato.h"
00018 #include "simple.h"
00019
00020
00021
00022
00023 static void sgnarea(struct vertex *l, struct vertex *m, int i[])
00024 {
00025 double a, b, c, d, e, f, g, h, t;
00026 a = l->pos.x;
00027 b = l->pos.y;
00028 c = after(l)->pos.x - a;
00029 d = after(l)->pos.y - b;
00030 e = m->pos.x - a;
00031 f = m->pos.y - b;
00032 g = after(m)->pos.x - a;
00033 h = after(m)->pos.y - b;
00034 t = (c * f) - (d * e);
00035 i[0] = ((t == 0) ? 0 : (t > 0 ? 1 : -1));
00036 t = (c * h) - (d * g);
00037 i[1] = ((t == 0) ? 0 : (t > 0 ? 1 : -1));
00038 i[2] = i[0] * i[1];
00039 }
00040
00041
00042 static int between(double f, double g, double h)
00043 {
00044 if ((f == g) || (g == h))
00045 return (0);
00046 return ((f < g) ? (g < h ? 1 : -1) : (h < g ? 1 : -1));
00047 }
00048
00049
00050 static int online(struct vertex *l, struct vertex *m, int i)
00051 {
00052 struct position a, b, c;
00053 a = l->pos;
00054 b = after(l)->pos;
00055 c = (i == 0) ? m->pos : after(m)->pos;
00056 return ((a.x == b.x) ? ((a.x == c.x)
00057 && (-1 !=
00058 between(a.y, c.y, b.y))) : between(a.x,
00059 c.x,
00060 b.x));
00061 }
00062
00063
00064 static int intpoint(struct vertex *l, struct vertex *m, double *x, double *y, int cond)
00065 {
00066 struct position ls, le, ms, me, pt1, pt2;
00067 double m1, m2, c1, c2;
00068
00069 if (cond <= 0)
00070 return (0);
00071 ls = l->pos;
00072 le = after(l)->pos;
00073 ms = m->pos;
00074 me = after(m)->pos;
00075
00076 switch (cond) {
00077
00078 case 3:
00079 if (ls.x == le.x) {
00080 *x = ls.x;
00081 *y = me.y + SLOPE(ms, me) * (*x - me.x);
00082 } else if (ms.x == me.x) {
00083 *x = ms.x;
00084 *y = le.y + SLOPE(ls, le) * (*x - le.x);
00085 } else {
00086 m1 = SLOPE(ms, me);
00087 m2 = SLOPE(ls, le);
00088 c1 = ms.y - (m1 * ms.x);
00089 c2 = ls.y - (m2 * ls.x);
00090 *x = (c2 - c1) / (m1 - m2);
00091 *y = ((m1 * c2) - (c1 * m2)) / (m1 - m2);
00092 }
00093 break;
00094
00095 case 2:
00096 if (online(l, m, 0) == -1) {
00097 pt1 = ms;
00098 pt2 =
00099 (online(m, l, 1) ==
00100 -1) ? ((online(m, l, 0) == -1) ? le : ls) : me;
00101 } else if (online(l, m, 1) == -1) {
00102 pt1 = me;
00103 pt2 =
00104 (online(l, m, 0) ==
00105 -1) ? ((online(m, l, 0) == -1) ? le : ls) : ms;
00106 } else {
00107
00108 if (online(m, l, 0) != -1)
00109 return 0;
00110 pt1 = ls;
00111 pt2 = le;
00112 }
00113
00114 *x = (pt1.x + pt2.x) / 2;
00115 *y = (pt1.y + pt2.y) / 2;
00116 break;
00117
00118 case 1:
00119 if ((ls.x - le.x) * (ms.y - ls.y) == (ls.y - le.y) * (ms.x - ls.x)) {
00120 *x = ms.x;
00121 *y = ms.y;
00122 } else {
00123 *x = me.x;
00124 *y = me.y;
00125 }
00126 }
00127 return (1);
00128 }
00129
00130
00131 void find_intersection(struct vertex *l,
00132 struct vertex *m,
00133 struct intersection ilist[], struct data *input)
00134 {
00135 double x, y;
00136 int i[3];
00137 sgnarea(l, m, i);
00138
00139 if (i[2] > 0)
00140 return;
00141
00142 if (i[2] < 0) {
00143 sgnarea(m, l, i);
00144 if (i[2] > 0)
00145 return;
00146 if (!intpoint
00147 (l, m, &x, &y, (i[2] < 0) ? 3 : online(m, l, ABS(i[0]))))
00148 return;
00149 }
00150
00151 else if (!intpoint(l, m, &x, &y, (i[0] == i[1]) ?
00152 2 * MAX(online(l, m, 0),
00153 online(l, m, 1)) : online(l, m, ABS(i[0]))))
00154 return;
00155
00156 if (input->ninters >= MAXINTS) {
00157 agerr(AGERR, "using too many intersections\n");
00158 exit(1);
00159 }
00160
00161 ilist[input->ninters].firstv = l;
00162 ilist[input->ninters].secondv = m;
00163 ilist[input->ninters].firstp = l->poly;
00164 ilist[input->ninters].secondp = m->poly;
00165 ilist[input->ninters].x = x;
00166 ilist[input->ninters].y = y;
00167 input->ninters++;
00168 }