/*! \brief Calculate distance on surface \param gs pointer to geosurf struct \param p1 from point \param p2 to point \param[out] dist distnace \param use_exag use exag for calculation \return 0 on error (points not in region) \return 1 on success */ int gs_distance_onsurf(geosurf * gs, float *p1, float *p2, float *dist, int use_exag) { Point3 *tmp; int np, i; float exag, length; if (in_vregion(gs, p1) && in_vregion(gs, p2)) { if (NULL == (tmp = gsdrape_get_segments(gs, p1, p2, &np))) { return (0); } length = 0.; if (use_exag) { exag = GS_global_exag(); tmp[0][Z] *= exag; for (i = 0; i < (np - 1); i++) { tmp[i + 1][Z] *= exag; length += GS_distance(tmp[i], tmp[i + 1]); } } else { for (i = 0; i < (np - 1); i++) { length += GS_distance(tmp[i], tmp[i + 1]); } } *dist = length; return (1); } return (0); }
/*! \brief Get line width \param gln line (geoline) \return line width */ float gv_line_length(geoline * gln) { int n; float length = 0.0; for (n = 0; n < gln->npts - 1; n++) { if (gln->p2) { length += GS_P2distance(gln->p2[n + 1], gln->p2[n]); } else { length += GS_distance(gln->p3[n + 1], gln->p3[n]); } } return (length); }
int Nviz_set_cplane_here(nv_data *data, int cplane, float sx, float sy) { float x, y, z, len, los[2][3]; float dx, dy, dz; float n, s, w, e; Point3 realto, dir; int id; geosurf *gs; if (GS_get_selected_point_on_surface(sx, sy, &id, &x, &y, &z)) { gs = gs_get_surf(id); if (gs) { realto[X] = x - gs->ox + gs->x_trans; realto[Y] = y - gs->oy + gs->y_trans; realto[Z] = z + gs->z_trans; } else return 0; } else { if (gsd_get_los(los, (short)sx, (short)sy)) { len = GS_distance(Gv.from_to[FROM], Gv.real_to); GS_v3dir(los[FROM], los[TO], dir); GS_v3mult(dir, len); realto[X] = Gv.from_to[FROM][X] + dir[X]; realto[Y] = Gv.from_to[FROM][Y] + dir[Y]; realto[Z] = Gv.from_to[FROM][Z] + dir[Z]; } else return 0; } Nviz_get_cplane_translation(data, cplane, &dx, &dy, &dz); GS_get_region(&n, &s, &w, &e); dx = realto[X] - (e - w) / 2.; dy = realto[Y] - (n - s) / 2.; Nviz_set_cplane_translation(data, cplane, dx, dy, dz); return 1; }
/*! \brief ADD \param gv view (geoview) \return ? */ int gsd_zup_twist(geoview * gv) { float fr_to[2][4]; float look_theta, pi; float alpha, beta; float zup[3], yup[3], zupmag, yupmag; pi = 4.0 * atan(1.0); /* *************************************************************** */ /* This block of code is used to keep pos z in the up direction, * correcting for SGI system default which is pos y in the up * direction. Involves finding up vectors for both y up and * z up, then determining angle between them. LatLon mode uses y as * up direction instead of z, so no correction necessary. Next rewrite, * we should use y as up for all drawing. */ GS_v3eq(fr_to[FROM], gv->from_to[FROM]); GS_v3eq(fr_to[TO], gv->from_to[TO]); /* neg alpha OK since sin(-x) = -sin(x) */ alpha = pi / 2.0 - acos(fr_to[FROM][Z] - fr_to[TO][Z]); zup[X] = fr_to[TO][X]; zup[Y] = fr_to[TO][Y]; if (sin(alpha)) { zup[Z] = fr_to[TO][Z] + 1 / sin(alpha); } else { zup[Z] = fr_to[FROM][Z] + 1.0; } zupmag = GS_distance(fr_to[FROM], zup); yup[X] = fr_to[TO][X]; yup[Z] = fr_to[TO][Z]; /* neg beta OK since sin(-x) = -sin(x) */ beta = pi / 2.0 - acos(fr_to[TO][Y] - fr_to[FROM][Y]); if (sin(beta)) { yup[Y] = fr_to[TO][Y] - 1 / sin(beta); } else { yup[Y] = fr_to[FROM][Y] + 1.0; } yupmag = GS_distance(fr_to[FROM], yup); look_theta = (1800.0 / pi) * acos(((zup[X] - fr_to[FROM][X]) * (yup[X] - fr_to[FROM][X]) + (zup[Y] - fr_to[FROM][Y]) * (yup[Y] - fr_to[FROM][Y]) + (zup[Z] - fr_to[FROM][Z]) * (yup[Z] - fr_to[FROM][Z])) / (zupmag * yupmag)); if (fr_to[TO][X] - fr_to[FROM][X] < 0.0) { look_theta = -look_theta; } if (fr_to[TO][Z] - fr_to[FROM][Z] < 0.0) { /* looking down */ if (fr_to[TO][Y] - fr_to[FROM][Y] < 0.0) { look_theta = 1800 - look_theta; } } else { /* looking up */ if (fr_to[TO][Y] - fr_to[FROM][Y] > 0.0) { look_theta = 1800 - look_theta; } } return ((int)(gv->twist + 1800 + look_theta)); }