The Tiny HTM Library
|
00001 00007 #ifndef HTM_GEOMETRY_H 00008 #define HTM_GEOMETRY_H 00009 00010 #include "common.h" 00011 00012 #ifdef __cplusplus 00013 extern "C" { 00014 #endif 00015 00016 00017 /* ================================================================ */ 00021 /* ================================================================ */ 00022 00025 struct htm_v3 { 00026 double x; 00027 double y; 00028 double z; 00029 }; 00030 00033 struct htm_sc { 00034 double lon; 00035 double lat; 00036 }; 00037 00045 HTM_INLINE enum htm_errcode htm_v3_init(struct htm_v3 *out, 00046 double x, 00047 double y, 00048 double z) 00049 { 00050 if (HTM_ISSPECIAL(x) || HTM_ISSPECIAL(y) || HTM_ISSPECIAL(z)) { 00051 return HTM_ENANINF; 00052 } else if (out == NULL) { 00053 return HTM_ENULLPTR; 00054 } 00055 out->x = x; 00056 out->y = y; 00057 out->z = z; 00058 return HTM_OK; 00059 } 00060 00071 HTM_INLINE enum htm_errcode htm_sc_init(struct htm_sc *out, 00072 double lon_deg, 00073 double lat_deg) 00074 { 00075 if (HTM_ISSPECIAL(lon_deg) || HTM_ISSPECIAL(lat_deg)) { 00076 return HTM_ENANINF; 00077 } else if (lat_deg < -90.0 || lat_deg > 90.0) { 00078 return HTM_ELAT; 00079 } else if (out == NULL) { 00080 return HTM_ENULLPTR; 00081 } 00082 out->lon = lon_deg; 00083 out->lat = lat_deg; 00084 return HTM_OK; 00085 } 00086 00090 HTM_INLINE void htm_v3_add(struct htm_v3 *out, 00091 const struct htm_v3 *v1, 00092 const struct htm_v3 *v2) 00093 { 00094 out->x = v1->x + v2->x; 00095 out->y = v1->y + v2->y; 00096 out->z = v1->z + v2->z; 00097 } 00098 00102 HTM_INLINE void htm_v3_sub(struct htm_v3 *out, 00103 const struct htm_v3 *v1, 00104 const struct htm_v3 *v2) 00105 { 00106 out->x = v1->x - v2->x; 00107 out->y = v1->y - v2->y; 00108 out->z = v1->z - v2->z; 00109 } 00110 00114 HTM_INLINE void htm_v3_neg(struct htm_v3 *out, const struct htm_v3 *v) 00115 { 00116 out->x = - v->x; 00117 out->y = - v->y; 00118 out->z = - v->z; 00119 } 00120 00124 HTM_INLINE void htm_v3_mul(struct htm_v3 *out, 00125 const struct htm_v3 *v, 00126 double s) 00127 { 00128 out->x = v->x * s; 00129 out->y = v->y * s; 00130 out->z = v->z * s; 00131 } 00132 00136 HTM_INLINE void htm_v3_div(struct htm_v3 *out, 00137 const struct htm_v3 *v, 00138 double s) 00139 { 00140 out->x = v->x / s; 00141 out->y = v->y / s; 00142 out->z = v->z / s; 00143 } 00144 00148 HTM_INLINE double htm_v3_dot(const struct htm_v3 *v1, 00149 const struct htm_v3 *v2) 00150 { 00151 return v1->x * v2->x + v1->y * v2->y + v1->z * v2->z; 00152 } 00153 00157 HTM_INLINE void htm_v3_cwise_mul(struct htm_v3 *out, 00158 const struct htm_v3 *v1, 00159 const struct htm_v3 *v2) 00160 { 00161 out->x = v1->x * v2->x; 00162 out->y = v1->y * v2->y; 00163 out->z = v1->z * v2->z; 00164 } 00165 00169 HTM_INLINE double htm_v3_norm2(const struct htm_v3 *v) 00170 { 00171 return v->x * v->x + v->y * v->y + v->z * v->z; 00172 } 00173 00176 HTM_INLINE double htm_v3_norm(const struct htm_v3 *v) 00177 { 00178 return sqrt(htm_v3_norm2(v)); 00179 } 00180 00184 HTM_INLINE void htm_v3_normalize(struct htm_v3 *out, const struct htm_v3 *v) 00185 { 00186 double norm = htm_v3_norm(v); 00187 out->x = v->x / norm; 00188 out->y = v->y / norm; 00189 out->z = v->z / norm; 00190 } 00191 00203 HTM_INLINE void htm_v3_rcross(struct htm_v3 *out, 00204 const struct htm_v3 *v1, 00205 const struct htm_v3 *v2) 00206 { 00207 double x1 = v2->x + v1->x; 00208 double x2 = v2->x - v1->x; 00209 double y1 = v2->y + v1->y; 00210 double y2 = v2->y - v1->y; 00211 double z1 = v2->z + v1->z; 00212 double z2 = v2->z - v1->z; 00213 out->x = y1 * z2 - z1 * y2; 00214 out->y = z1 * x2 - x1 * z2; 00215 out->z = x1 * y2 - y1 * x2; 00216 } 00217 00221 HTM_INLINE void htm_v3_cross(struct htm_v3 *out, 00222 const struct htm_v3 *v1, 00223 const struct htm_v3 *v2) 00224 { 00225 double x = v1->y * v2->z - v1->z * v2->y; 00226 double y = v1->z * v2->x - v1->x * v2->z; 00227 double z = v1->x * v2->y - v1->y * v2->x; 00228 out->x = x; 00229 out->y = y; 00230 out->z = z; 00231 } 00232 00240 enum htm_errcode htm_v3_ne(struct htm_v3 *north, 00241 struct htm_v3 *east, 00242 const struct htm_v3 *v); 00243 00257 enum htm_errcode htm_v3_tanrot(double *angle, 00258 const struct htm_v3 *v1, 00259 const struct htm_v3 *v2, 00260 double r); 00261 00270 enum htm_errcode htm_v3_rot(struct htm_v3 *out, 00271 const struct htm_v3 *v, 00272 const struct htm_v3 *k, 00273 double angle_deg); 00274 00282 enum htm_errcode htm_v3_centroid(struct htm_v3 *cen, 00283 const struct htm_v3 *points, 00284 size_t n); 00285 00293 enum htm_errcode htm_sc_tov3(struct htm_v3 *out, const struct htm_sc *p); 00294 00302 enum htm_errcode htm_v3_tosc(struct htm_sc *out, const struct htm_v3 *v); 00303 00304 00305 /* ================================================================ */ 00310 /* ================================================================ */ 00311 00316 double htm_sc_dist2(const struct htm_sc *p1, const struct htm_sc *p2); 00317 00321 double htm_sc_angsep(const struct htm_sc *p1, const struct htm_sc *p2); 00322 00326 HTM_INLINE double htm_v3_dist2(const struct htm_v3 *v1, 00327 const struct htm_v3 *v2) 00328 { 00329 struct htm_v3 delta; 00330 htm_v3_sub(&delta, v1, v2); 00331 return htm_v3_norm2(&delta); 00332 } 00333 00337 double htm_v3_angsepu(const struct htm_v3 *v1, 00338 const struct htm_v3 *v2); 00339 00344 double htm_v3_angsep(const struct htm_v3 *v1, const struct htm_v3 *v2); 00345 00351 double htm_v3_edgedist2(const struct htm_v3 *v, 00352 const struct htm_v3 *v1, 00353 const struct htm_v3 *v2, 00354 const struct htm_v3 *e); 00355 00356 00357 /* ================================================================ */ 00362 /* ================================================================ */ 00363 00371 struct htm_s2ellipse { 00372 struct htm_v3 cen; 00373 double xx; 00374 double yy; 00375 double zz; 00376 double xy; 00377 double xz; 00378 double yz; 00379 double a; 00380 }; 00381 00385 enum htm_errcode htm_s2ellipse_init(struct htm_s2ellipse *e, 00386 const struct htm_v3 *f1, 00387 const struct htm_v3 *f2, 00388 double a); 00389 00395 enum htm_errcode htm_s2ellipse_init2(struct htm_s2ellipse *e, 00396 const struct htm_v3 *cen, 00397 double a, 00398 double b, 00399 double angle); 00400 00404 HTM_INLINE int htm_s2ellipse_cv3(const struct htm_s2ellipse *e, 00405 const struct htm_v3 *v) 00406 { 00407 double qf = e->xx * v->x * v->x + 00408 e->yy * v->y * v->y + 00409 e->zz * v->z * v->z + 00410 2.0 * e->xy * v->x * v->y + 00411 2.0 * e->xz * v->x * v->z + 00412 2.0 * e->yz * v->y * v->z; 00413 double dp = htm_v3_dot(&e->cen, v); 00414 if (e->a <= 90.0) { 00415 return dp >= 0.0 && qf <= 0.0; 00416 } 00417 return dp >= 0.0 || qf >= 0.0; 00418 } 00419 00420 00421 /* ================================================================ */ 00426 /* ================================================================ */ 00427 00433 struct htm_s2cpoly { 00434 size_t n; 00435 struct htm_v3 vsum; 00436 struct htm_v3 ve[]; 00437 }; 00438 00441 HTM_INLINE struct htm_v3 * htm_s2cpoly_verts(struct htm_s2cpoly *poly) 00442 { 00443 return poly->ve; 00444 } 00445 00448 HTM_INLINE struct htm_v3 * htm_s2cpoly_edges(struct htm_s2cpoly *poly) 00449 { 00450 return poly->ve + poly->n; 00451 } 00452 00469 struct htm_s2cpoly * htm_s2cpoly_init(const struct htm_v3 *verts, 00470 size_t n, 00471 enum htm_errcode *err); 00472 00487 struct htm_s2cpoly * htm_s2cpoly_box(const struct htm_v3 *cen, 00488 double width, 00489 double height, 00490 double angle, 00491 enum htm_errcode *err); 00492 00504 struct htm_s2cpoly * htm_s2cpoly_ngon(const struct htm_v3 *cen, 00505 double r, 00506 size_t n, 00507 enum htm_errcode *err); 00508 00521 struct htm_s2cpoly * htm_s2cpoly_line(const struct htm_v3 *v1, 00522 const struct htm_v3 *v2, 00523 double r, 00524 enum htm_errcode *err); 00525 00529 int htm_s2cpoly_cv3(const struct htm_s2cpoly *poly, const struct htm_v3 *v); 00530 00534 double htm_s2cpoly_area(const struct htm_s2cpoly *poly); 00535 00541 struct htm_s2cpoly * htm_s2cpoly_clone(const struct htm_s2cpoly *poly); 00542 00545 enum htm_errcode htm_s2cpoly_pad(struct htm_s2cpoly *poly, double r); 00546 00547 00548 /* ================================================================ */ 00553 /* ================================================================ */ 00554 00559 int htm_v3_hemispherical(const struct htm_v3 *points, 00560 size_t n, 00561 enum htm_errcode *err); 00562 00574 int htm_v3_convex(const struct htm_v3 *points, 00575 size_t n, 00576 enum htm_errcode *err); 00577 00589 struct htm_s2cpoly * htm_s2cpoly_hull(const struct htm_v3 *points, 00590 size_t n, 00591 enum htm_errcode *err); 00592 00596 #ifdef __cplusplus 00597 } 00598 #endif 00599 00600 #endif /* HTM_GEOMETRY_H */ 00601