/* rotation of a sphere */ void SPHERE_Rotate (SPHERE *sph, double *point, double *vector, double angle) { double R [9], omega [3]; double (*ref_pnt) [3] = sph->ref_point, (*cur_pnt) [3] = sph->cur_point; angle *= ALG_PI / 180.0; COPY (vector, omega); NORMALIZE (omega); SCALE (omega, angle); EXPMAP (omega, R); SUB (sph->cur_center, point, omega); NVADDMUL (point, R, omega, sph->cur_center); COPY (sph->cur_center, sph->ref_center); for (int i = 0; i < 3; i ++) { SUB (cur_pnt [i], point, omega); NVADDMUL (point, R, omega, cur_pnt [i]); COPY (cur_pnt [i], ref_pnt [i]); } }
/* rotation of a ellipsoid */ void ELLIP_Rotate (ELLIP *eli, double *point, double *vector, double angle) { double R [9], omega [3]; double *ref [4] = {eli->ref_center, eli->ref_point [0], eli->ref_point [1], eli->ref_point [2]}; angle *= ALG_PI / 180.0; COPY (vector, omega); NORMALIZE (omega); SCALE (omega, angle); EXPMAP (omega, R); for (int i = 0; i < 4; i ++) { SUB (ref [i], point, omega); NVADDMUL (point, R, omega, ref [i]); } ELLIP_Update (eli, NULL, NULL, NULL); }
} if (!p) return (RES_color (RID_GMRC_BG_DEFAULT)); return (RES_color (p->rid)); } /* ------------------------------------------------------------ */ typedef struct s_GUI_EXP_MAP { SPWAW_EXP id; unsigned long rid; } GUI_EXP_MAP; #define EXPMAP(id_,map_) { SPWAW_E##id_, RID_GMRC_EXP_##map_ } static GUI_EXP_MAP expmap[SPWAW_EXP_CNT] = { EXPMAP (CADET, CAD), EXPMAP (GREEN, GRN), EXPMAP (AVERAGE, AVG), EXPMAP (VETERAN, VET), EXPMAP (ELITE, ELT), }; static GUI_EXP_MAP *expmap_cache[SPWAW_EXP_CNT] = { 0 }; QColor * RES_GUI_color (SPWAW_EXP id) { GUI_EXP_MAP *p; if (!(p = expmap_cache[id])) { for (int i=0; i<SPWAW_EXP_CNT; i++)
/* generate test */ static void gen () { double d [3], move [3]; switch (mode) { case GJK_CONVEX_CONVEX: { asize = bsize = 0; while (asize < minim) asize = rand () % limit; while (bsize < minim) bsize = rand () % limit; SETRAND (move, 1.0); for (int n = 0; n < asize; n ++) { SETRAND (apoint [n], 0.75); ADD (apoint [n], move, apoint [n]); } for (int n = 0; n < bsize; n ++) { SETRAND (bpoint [n], 0.75); SUB (bpoint [n], move, bpoint [n]); } free (a); free (b); a = hull ((double*)apoint, asize, &alength); b = hull ((double*)bpoint, bsize, &blength); double *va, *vb; int nva, nvb; va = TRI_Vertices (a, alength, &nva); vb = TRI_Vertices (b, blength, &nvb); gjk (va, nva, vb, nvb, p, q); free (va); free (vb); } break; case GJK_CONVEX_SPHERE: { asize = bsize = 0; while (asize < minim) asize = rand () % limit; SETRAND (move, 1.0); for (int n = 0; n < asize; n ++) { SETRAND (apoint [n], 0.75); ADD (apoint [n], move, apoint [n]); } free (a); a = hull ((double*)apoint, asize, &alength); SETRAND (center, 1.0); SUB (center, move, center); radius = 0.75 * DRAND (); double *va; int nva; va = TRI_Vertices (a, alength, &nva); gjk_convex_sphere (va, nva, center, radius, p, q); free (va); } break; case GJK_CONVEX_POINT: { asize = bsize = 0; while (asize < minim) asize = rand () % limit; SETRAND (move, 1.0); for (int n = 0; n < asize; n ++) { SETRAND (apoint [n], 0.75); ADD (apoint [n], move, apoint [n]); } free (a); a = hull ((double*)apoint, asize, &alength); SETRAND (center, 1.0); SUB (center, move, center); radius = 0.0; double *va; int nva; va = TRI_Vertices (a, alength, &nva); COPY (center, p); gjk_convex_point (va, nva, p, q); free (va); } break; case GJK_CONVEX_ELLIP: { asize = bsize = 0; while (asize < minim) asize = rand () % limit; SETRAND (move, 1.0); for (int n = 0; n < asize; n ++) { SETRAND (apoint [n], 0.75); ADD (apoint [n], move, apoint [n]); } free (a); a = hull ((double*)apoint, asize, &alength); SETRAND (el1_center, 1.0); SUB (el1_center, move, el1_center); el1_sca [0] = 0.75 * DRAND (); el1_sca [1] = 0.75 * DRAND (); el1_sca [2] = 0.75 * DRAND (); EXPMAP (el1_sca, el1_rot); double *va; int nva; va = TRI_Vertices (a, alength, &nva); gjk_convex_ellip (va, nva, el1_center, el1_sca, el1_rot, p, q); free (va); } break; case GJK_SPHERE_ELLIP: { SETRAND (move, 1.0); SETRAND (center, 1.0); radius = 0.75 * DRAND (); SETRAND (el1_center, 1.0); SUB (el1_center, move, el1_center); el1_sca [0] = 0.75 * DRAND (); el1_sca [1] = 0.75 * DRAND (); el1_sca [2] = 0.75 * DRAND (); EXPMAP (el1_sca, el1_rot); gjk_sphere_ellip (center, radius, el1_center, el1_sca, el1_rot, p, q); } break; case GJK_ELLIP_ELLIP: { SETRAND (move, 1.0); SETRAND (el1_center, 1.0); el1_sca [0] = 0.75 * DRAND (); el1_sca [1] = 0.75 * DRAND (); el1_sca [2] = 0.75 * DRAND (); EXPMAP (el1_sca, el1_rot); SETRAND (el2_center, 1.0); SUB (el2_center, move, el2_center); el2_sca [0] = 0.75 * DRAND (); el2_sca [1] = 0.75 * DRAND (); el2_sca [2] = 0.75 * DRAND (); EXPMAP (el2_sca, el2_rot); gjk_ellip_ellip (el1_center, el1_sca, el1_rot, el2_center, el2_sca, el2_rot, p, q); } break; case GJK_ELLIP_POINT: { SETRAND (move, 1.0); SETRAND (el1_center, 1.0); el1_sca [0] = 0.75 * DRAND (); el1_sca [1] = 0.75 * DRAND (); el1_sca [2] = 0.75 * DRAND (); EXPMAP (el1_sca, el1_rot); SETRAND (center, 1.0); SUB (center, move, center); radius = 0.0; COPY (center, p); gjk_ellip_point (el1_center, el1_sca, el1_rot, p, q); } break; } SUB (p, q, d); printf ("|p-q|=%g\n", LEN (d)); }