The Tiny HTM Library
include/tinyhtm/geometry.h
Go to the documentation of this file.
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