60 #define DONT_INTERSECT 0
61 #define DO_INTERSECT 1
64 #define LERP(a, l, h) ((l) + (((h) - (l)) * (a)))
65 #define EQUAL(a, b) (fabs((a) - (b)) < EPSILON)
66 #define ISNODE(p, res) (fmod((double)p, (double)res) < EPSILON)
68 #define SAME_SIGNS(a, b) ((a >= 0 && b >= 0) || (a < 0 && b < 0))
70 static int drape_line_init(
int,
int);
71 static Point3 *_gsdrape_get_segments(
geosurf *,
float *,
float *,
int *);
72 static float dist_squared_2d(
float *,
float *);
78 static float EPSILON = 0.000001;
81 static Point3 *Vi, *Hi, *Di;
95 static int drape_line_init(
int rows,
int cols)
136 static Point3 *_gsdrape_get_segments(
geosurf *gs,
float *bgn,
float *end,
141 float dir[2], yres, xres;
157 if (!((end[
Y] - bgn[
Y]) / (end[
X] - bgn[
X]) == yres / xres)) {
166 G_debug(5,
"_gsdrape_get_segments vi=%d, hi=%d, di=%d, num=%d", vi, hi, di,
180 static float dist_squared_2d(
float *p1,
float *p2)
187 return (dx * dx + dy * dy);
200 static int first = 1;
205 if (0 > drape_line_init(gs->
rows, gs->
cols)) {
206 G_warning(
_(
"Unable to process vector map - out of memory"));
235 float *replace, xl, yb, xr, yt, xi, yi;
280 float pt1[2], pt2[2];
373 if (bgn[
X] == end[
X] && bgn[
Y] == end[
Y]) {
387 return (_gsdrape_get_segments(gs, bgn, end, num));
409 if (bgn[
X] == end[
X] && bgn[
Y] == end[
Y]) {
427 return (_gsdrape_get_segments(gs, bgn, end, num));
512 int offset, drow, dcol, vrow, vcol;
513 float xmax, ymin, ymax, alpha;
525 if (pt[
X] < 0.0 || pt[
Y] > ymax) {
530 if (pt[
Y] < ymin || pt[
X] > xmax) {
549 if (pt[
X] > 0.0 && pt[
Y] < ymax) {
555 offset =
DRC2OFF(gs, drow, dcol);
562 offset =
DRC2OFF(gs, drow, dcol);
571 offset =
DRC2OFF(gs, drow, dcol);
580 offset =
DRC2OFF(gs, drow, dcol);
586 else if (pt[
X] == 0.0) {
599 pt[
Z] =
LERP(alpha, p1[
Z], p2[
Z]);
608 else if (pt[
Y] == gs->
yrange) {
618 pt[
Z] =
LERP(alpha, p1[
Z], p2[
Z]);
623 else if (vrow ==
VROWS(gs)) {
627 if (pt[
X] > 0.0 && pt[
X] < xmax) {
631 offset =
DRC2OFF(gs, drow, dcol);
635 offset =
DRC2OFF(gs, drow, dcol);
639 pt[
Z] =
LERP(alpha, p1[
Z], p2[
Z]);
643 else if (pt[
X] == 0.0) {
653 offset =
DRC2OFF(gs, drow, dcol);
666 offset =
DRC2OFF(gs, drow, dcol);
670 offset =
DRC2OFF(gs, drow, dcol);
674 pt[
Z] =
LERP(alpha, p1[
Z], p2[
Z]);
700 if (pt[
X] >= 0.0 && pt[
Y] <= gs->
yrange) {
734 int num, i, found, cv, ch, cd, cnum;
735 float dv, dh, dd, big, cpoint[2];
737 cv = ch = cd = cnum = 0;
740 cpoint[
X] = first[
X];
741 cpoint[
Y] = first[
Y];
744 I3d[cnum][
X] = first[
X];
745 I3d[cnum][
Y] = first[
Y];
746 I3d[cnum][
Z] = first[
Z];
754 for (i = 0; i < num; i = cv + ch + cd) {
756 dv = dist_squared_2d(Vi[cv], cpoint);
768 dh = dist_squared_2d(Hi[ch], cpoint);
780 dd = dist_squared_2d(Di[cd], cpoint);
794 if (dd <= dv && dd <= dh) {
796 cpoint[
X] = I3d[cnum][
X] = Di[cd][
X];
797 cpoint[
Y] = I3d[cnum][
Y] = Di[cd][
Y];
798 I3d[cnum][
Z] = Di[cd][
Z];
817 cpoint[
X] = I3d[cnum][
X] = Vi[cv][
X];
818 cpoint[
Y] = I3d[cnum][
Y] = Vi[cv][
Y];
819 I3d[cnum][
Z] = Vi[cv][
Z];
833 cpoint[
X] = I3d[cnum][
X] = Hi[ch][
X];
834 cpoint[
Y] = I3d[cnum][
Y] = Hi[ch][
Y];
835 I3d[cnum][
Z] = Hi[ch][
Z];
841 if (i == cv + ch + cd) {
842 G_debug(5,
"order_intersects(): stuck on %d", cnum);
843 G_debug(5,
"order_intersects(): cv = %d, ch = %d, cd = %d", cv, ch,
845 G_debug(5,
"order_intersects(): dv = %f, dh = %f, dd = %f", dv, dh,
858 I3d[cnum][
X] = last[
X];
859 I3d[cnum][
Y] = last[
Y];
860 I3d[cnum][
Z] = last[
Z];
886 int fcol, lcol, incr, hits, num, offset, drow1, drow2;
887 float xl, yb, xr, yt, z1, z2, alpha;
889 int bgncol, endcol, cols, rows;
898 if (bgncol > cols && endcol > cols) {
902 if (bgncol == endcol) {
906 fcol = dir[
X] > 0 ? bgncol + 1 : bgncol;
907 lcol = dir[
X] > 0 ? endcol : endcol + 1;
910 incr = lcol - fcol > 0 ? 1 : -1;
912 while (fcol > cols || fcol < 0) {
916 while (lcol > cols || lcol < 0) {
920 num = abs(lcol - fcol) + 1;
925 for (hits = 0; hits < num; hits++) {
926 xl = xr =
VCOL2X(gs, fcol);
941 if (drow2 >= gs->
rows) {
942 drow2 = gs->
rows - 1;
945 alpha = ((gs->
yrange - drow1 * gs->
yres) - Vi[hits][
Y]) / yres;
951 Vi[hits][
Z] =
LERP(alpha, z1, z2);
980 int frow, lrow, incr, hits, num, offset, dcol1, dcol2;
981 float xl, yb, xr, yt, z1, z2, alpha;
983 int bgnrow, endrow, rows, cols;
991 if (bgnrow == endrow) {
995 if (bgnrow > rows && endrow > rows) {
999 frow = dir[
Y] > 0 ? bgnrow : bgnrow + 1;
1000 lrow = dir[
Y] > 0 ? endrow + 1 : endrow;
1003 incr = lrow - frow > 0 ? 1 : -1;
1005 while (frow > rows || frow < 0) {
1009 while (lrow > rows || lrow < 0) {
1013 num = abs(lrow - frow) + 1;
1018 for (hits = 0; hits < num; hits++) {
1019 yb = yt =
VROW2Y(gs, frow);
1034 if (dcol2 >= gs->
cols) {
1035 dcol2 = gs->
cols - 1;
1038 alpha = (Hi[hits][
X] - (dcol1 * gs->
xres)) / xres;
1044 Hi[hits][
Z] =
LERP(alpha, z1, z2);
1075 int fdig, ldig, incr, hits, num, offset;
1076 int vrow, vcol, drow1, drow2, dcol1, dcol2;
1077 float xl, yb, xr, yt, z1, z2, alpha;
1078 float xres, yres, xi, yi, dx, dy;
1079 int diags, cols, rows, lower;
1086 diags = rows + cols;
1093 lower = ((end[
X] - pt[
X]) / xres > (end[
Y] - pt[
Y]) / yres);
1094 ldig = lower ? vrow + vcol + 1 : vrow + vcol;
1101 lower = ((bgn[
X] - pt[
X]) / xres > (bgn[
Y] - pt[
Y]) / yres);
1102 fdig = lower ? vrow + vcol + 1 : vrow + vcol;
1113 incr = ldig - fdig > 0 ? 1 : -1;
1115 while (fdig > diags || fdig < 0) {
1119 while (ldig > diags || ldig < 0) {
1123 num = abs(ldig - fdig) + 1;
1125 for (hits = 0; hits < num; hits++) {
1126 yb = gs->
yrange - (yres * (fdig < rows ? fdig : rows)) -
EPSILON;
1128 yt = gs->
yrange - (yres * (fdig < cols ? 0 : fdig - cols)) +
EPSILON;
1147 if (drow2 >= gs->
rows) {
1148 drow2 = gs->
rows - 1;
1159 if (dcol2 >= gs->
cols) {
1160 dcol2 = gs->
cols - 1;
1163 dx =
DCOL2X(gs, dcol2) - Di[hits][
X];
1164 dy =
DROW2Y(gs, drow1) - Di[hits][
Y];
1166 sqrt(dx * dx + dy * dy) / sqrt(xres * xres + yres * yres);
1168 offset =
DRC2OFF(gs, drow1, dcol2);
1170 offset =
DRC2OFF(gs, drow2, dcol1);
1172 Di[hits][
Z] =
LERP(alpha, z1, z2);
1210 float x4,
float y4,
float *
x,
float *y)
1212 float a1, a2, b1, b2, c1, c2;
1213 float r1, r2, r3, r4;
1221 c1 = x2 * y1 - x1 * y2;
1225 r3 = a1 * x3 + b1 * y3 + c1;
1226 r4 = a1 * x4 + b1 * y4 + c1;
1239 c2 = x4 * y3 - x3 * y4;
1242 r1 = a2 * x1 + b2 * y1 + c2;
1243 r2 = a2 * x2 + b2 * y2 + c2;
1256 denom = a1 * b2 - a2 * b1;
1268 num = b1 * c2 - b2 * c1;
1272 num = a2 * c1 - a1 * c2;
1338 v1[
X] = p1[
X] - p3[
X];
1339 v1[
Y] = p1[
Y] - p3[
Y];
1340 v1[
Z] = p1[
Z] - p3[
Z];
1342 v2[
X] = p2[
X] - p3[
X];
1343 v2[
Y] = p2[
Y] - p3[
Y];
1344 v2[
Z] = p2[
Z] - p3[
Z];
1351 plane[
W] = -p3[
X] * norm[
X] - p3[
Y] * norm[
Y] - p3[
Z] * norm[
Z];
1366 c[
X] = (a[
Y] *
b[
Z]) - (a[
Z] *
b[
Y]);
1367 c[
Y] = (a[
Z] *
b[
X]) - (a[
X] *
b[
Z]);
1368 c[
Z] = (a[
X] *
b[
Y]) - (a[
Y] *
b[
X]);
void G_free(void *)
Free allocated memory.
void G_warning(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
int gs_point_is_masked(geosurf *, float *)
Check if point is masked.
float GS_P2distance(float *, float *)
Calculate distance in plane.
int gs_get_att_src(geosurf *, int)
Get attribute source.
void GS_v3eq(float *, float *)
Copy vector values.
typbuff * gs_get_att_typbuff(geosurf *, int, int)
Get attribute data buffer.
void GS_v2dir(float *, float *, float *)
Get a normalized direction from v1 to v2, store in v3 (2D)
#define UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
int P3toPlane(Point3 p1, Point3 p2, Point3 p3, float *plane)
Define plane.
int in_vregion(geosurf *gs, float *pt)
ADD.
Point3 * gsdrape_get_segments(geosurf *gs, float *bgn, float *end, int *num)
ADD.
int order_intersects(geosurf *gs, Point3 first, Point3 last, int vi, int hi, int di)
ADD.
int _viewcell_tri_interp(geosurf *gs, Point3 pt)
ADD.
Point3 * gsdrape_get_allsegments(geosurf *gs, float *bgn, float *end, int *num)
Get all segments.
int gsdrape_set_surface(geosurf *gs)
ADD.
void interp_first_last(geosurf *gs, float *bgn, float *end, Point3 f, Point3 l)
ADD.
int V3Cross(Point3 a, Point3 b, Point3 c)
Get cross product.
int viewcell_tri_interp(geosurf *gs, typbuff *buf, Point3 pt, int check_mask)
ADD.
int segs_intersect(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float *x, float *y)
Line intersect.
int get_horz_intersects(geosurf *gs, float *bgn, float *end, float *dir)
Get horizontal intersects.
int get_vert_intersects(geosurf *gs, float *bgn, float *end, float *dir)
ADD.
int get_diag_intersects(geosurf *gs, float *bgn, float *end, float *dir)
Get diagonal intersects.
int seg_intersect_vregion(geosurf *gs, float *bgn, float *end)
Check if segment intersect vector region.
int XY_intersect_plane(float *intersect, float *plane)
Check for intersection (point and plane)
int Point_on_plane(Point3 p1, Point3 p2, Point3 p3, Point3 unk)
Check if point is on plane.
#define GET_MAPATT(buff, offset, att)
OGSF header file (structures)
#define DRC2OFF(gs, drow, dcol)
#define VROW2DROW(gs, vrow)
#define VCOL2DCOL(gs, vcol)
gsurf_att att[7]
mask, topo, color, etc.
int x_mod
cells per viewcell, per wire viewcell