Functions performing Nemo Library geometry productions on the surface of a sphere. In this library, the sphere will typically be an ellipsoid-specific near-conformal unit sphere, "NCS". See the preamble of the ellipsoid geometry library section for additional NCS commentary.

nemo_SphereRandomLocation() | Generate a random location on unit sphere |

nemo_SphereRandomLine() | Generate random line on unit sphere |

nemo_RandomLocal() | Generate regional random point on unit sphere |

nemo_SphereCircumcenter() | Find spherical circumcenter |

nemo_SphereTangentialPlane() | Principal vectors of tangential plane |

nemo_SphereChordDirect() | Direct problem of geodesy on sphere |

nemo_SphereChordInverse() | Inverse problem of geodesy on sphere |

nemo_SphereChordCoords() | Spherical Abscissa and Ordinate |

nemo_SphereSegsXsct() | Intersection of two great circle segments |

Synopsis:#include <nemo.h> nemoPtNcs *nemo_SphereRandomLocation(nemoPtNcs *pRandNcs);

Test data generation example: 16 clusters of random global locations

Description:Generate a random, uniformaly distributed location on a unit sphere. · The function starts by generating a random point in a cube tightly encompassing a sphere with RAND_MAX radius. Points are rejected if outside the sphere, or if their radius-vector is so small that the normalization might be numerically problematic; otherwise their radius-vector is normalized. Assuming original points are generated with uniform density inside the cube, the resulting points will cover the surface of the sphere with an "uniformly random" distribution. Using this function as a "primitive", an application can (see the illustration above) generate specific patterns of globally distributed points to fit specific geometry tests or spatial algorithms benchmarking scenarios. · The function uses C math library rand() function, see its documentation for the consequences of seeding it (or absence of it). Hint: an application should probably call srand(time(0)) before the first call to this function.Argument:pRandNCS: Pointer to nemoPtNcs structure, returned random point or NULL. If the argument is NULL, an internal static structure memory will be used for generated location, in which case the function will not be "thread-safe".Return Value:Pointer to the nemoPtNcs structure with the generated random location on the unit sphere. (cf.,pRandNCSargument).See Also:nemo_SphereRandomLine()

nemo_RandomLocal()

Synopsis:#include <nemo.h> void nemo_SphereRandomLine(const nemoPtNcs *ptNcs, double arc, nemoPtNcs *pRlnNcsA, nemoPtNcs *pRlnNcsB);

Approximation of geodesic by NSC arc scaled to ellipsoid.

Description:Given a line mid-point, generate a random line of a given arc length on the unit sphere. Similar to the nemo_SphereRandomLocation(), this function is used in testing, benchmarking and visual confirmation of geodetic propositions; as in the map above, which illustrates the dependency on latitude of the quality of approximation of geodesic using NCS arc scaled up to the ellipsoid (using NCS to ellipsoid scale factor calculated by nemo_NcsElrScale() at the line mid-point).Arguments:ptNcs: Pointer to nemoPtNcs structure, mid-pint of the line (usually generated using nemo_SphereRandomLocation() function; arc: double, the length of the line, defined by its spherical arc, (with π as the maximum). pRlnNcsA, pRlnNcsB: Pointers to nemoPtNcs structure, returned start and end point of the line.See Also:nemo_SphereRandomLocation()

nemo_RandomLocal()

nemo_SphereChordDirect()

Synopsis:#include <nemo.h> void nemo_RandomLocal(const nemoPtNcs *ptNcs, double arc, double parms[NEMO_GNOMONIC_PCNT], nemoPtNcs *pRandNcs);Description:This function is similar to its two sibling, but instead of creating a random object uniformly distributed over the entire planetary surface, the object (point) is distributed, with somewhat less uniform distribution, over a smaller region defined by its centre and unit sphere arc radius. · The function internally generates a random point in the gnomonic projection plane, and "un-maps" the planar point back to sphere. It is therefore quite adequate for benchmarking/testing in regions with radius an order of magnitude smaller that the planet radius. . In addition to its primary purpose, the function provides an example of purposeful use of spherical gnomonic projection to deal with the spherical phenomena of limited spatial extent.Arguments:ptNcs: Pointer to nemoPtNcs structure, center of the region of the required set of uniformally-distributed random spherical points. arc: Unit sphere radius of the region. parms: An array of doubles, Gnomonic projection parametars. Before the first invocation of the function in theptNcsvicinity, the element [0] of the array should be set to NEMO_DOUBLE_UNDEF so that the function code can initialize the array (by an internal call to nemo_GnomonicInit()). pRandNcs: Pointer to nemoPtNcs structure, returned random point or NULL. If the argument is NULL, an internal static structure memory will be used for generated location, in which case the function will not be "thread-safe".Return Value:Pointer to the nemoPtNcs structure with the generated random location on the unit sphere (cf.,pRandNCSargument), the locus as defined above.See Also:nemo_SphereRandomLocation()

nemo_GnomonicInit()

Synopsis:#include <nemo.h> int nemo_SphereCircumcenter(const nemoPtNcs *pA, const nemoPtNcs *pB, const nemoPtNcs *pC, nemoPtNcs *pCntr);

Circumcenter of Odessa, Boston and Dakar

Description:Given are three points on the sphere, find the point that is equidistant from all three given points. · Since on the sphere there are always two such points - "near" and "far", the order of three given points is significant: it must be in the mathematically positive direction (i.e., counterclockwise) when observed from above the sphere onto the tangential plane at the expected cicumcenter.Arguments:pA, pB, pC: Pointers to nemoPtNcs structures, three given spherical points. pCnrt: Pointer to a receiving nemoPtNcs structure, returned coordinates of the circumcenter.Return Value:integer, computation result/status indicator: = 1 if the circumcenter is the near pole of the small circle defined by three given given points. = -1 opposite from the above; i.e., the circumcenter is the far pole of the small circle. = 0 if the given points are on, or close to a great circle of the sphere. = 2 if the geometry is ill-defined because any two (or all three) )given points are coincident.See Also:nemo_SphereChordCoords()

nemo_SphereSegsXsct()

Synopsis:#include <nemo.h> void nemo_SphereTangentialPlane(const nemoPtNcs *ptNcs, nemoDxCc3 *dxPrv, nemoDxCc3 *dxMrd);Description:Find two 3-dimensional vectors that define the tangential plane to the spherical surface in any given point on its surface. The two directions are normals to Prime Vertical and Meridian planes in the given point. Since the orientation of directions is undefined on the Poles, by convention the Prime Vertical normal coincides with the positive direction of X coordinate axis on North, and negative direction on the South Pole.Arguments:ptNcs: Pointer to nemoPtNcs structure, given spherical point. dxPrv: pointer to nemoDxCc3 structure, returned Prime Vertical normal. dxMrd: pointer to nemoDxCc3 structure, returned Meridian plane normal.

Synopsis:#include <nemo.h> int nemo_SphereChordDirect(const nemoPtNcs *pPtA, const nemoDxPln *pDxAB, double chord, nemoPtNcs *pPtB);Description:Solve "direct problem of geodesy" on the spherical surface: given are coordinates of a point, the azimuth and the distance (here defined by its spherical cord), find the end-point of the line.Arguments:pPtA: Pointer to nemoPtNcs structure, given spherical point. pDxAB: Pointer to nemoDxPln structure, given direction frompPtAtopPtBin the tangential plane ofpPtA. chord: Double, distance frompPtAtopPtBdefined by its spherical chord. pPtB: Pointer to nemoPtNcs structure, returned spherical point.Return Value:integer, status indicator, 1 if the chord distance is close to spherical diameter (where the geometry becomes ill-defined), 0 otherwise.See Also:nemo_SphereChordInverse()

Synopsis:#include <nemo.h> double nemo_SphereChordInverse(const nemoPtNcs *pPtA, const nemoPtNcs *pPtB, nemoDxPln *pDxAB, nemoDxPln *pDxBA);Description:Solve the "second geodetic problem" on the spherical surface: given are coordinates of two non-coincident points, find the length of the chord between them and, in each given point the tangential plane direction of the line to the other given point. (2-nd problem is also called "inverse geodetic problem").Arguments:pPtA: Pointer to nemoPtNcs structure, first given spherical point. pPtB: Pointer to nemoPtNcs structure, second given spherical point. pDxAB: Pointer to nemoDxPln structure or NULL, returned direction frompPtAtopPtBin the tangential plane ofpPtA. pDxBA: Pointer to nemoDxPln structure or NULL, returned direction frompPtBtopPtAin the tangential plane ofpPtB. (If either of two direction pointers are NULL, the invoker does not require the respective direction).Return Value:Double, square of the chord distance betweenpPtAandpPtB.See Also:nemo_SphereChordDirect()

Synopsis:#include <nemo.h> int nemo_SphereChordCoords(const nemoPtNcs *pPtA, const nemoPtNcs *pPtB, const nemoPtNcs *pPtY, nemoPtNcs *pPtX, double *pAX, double *pBX, double *pXY);

Abscissa and ordinate of Y for great circle segment A, B

Description:Spherical equivalent of the simple Cartesian proposition: given are two points that define a right-handed cartesian cordinate system and an arbitrary surface point, determine that point's abscissa and ordinate. Coordinate axes are great circles, and the first given points is assumed to be the coordinate system origin. All returned distances are spherical chords squared.Arguments:pPtA: Pointer to nemoPtNcs structure, first given spherical point, coordinate system origin. pPtB: Pointer to nemoPtNcs structure, second given spherical point, defining (with thepPtA) the abscissa of the right-handed coordinate system. pPtY: Pointer to nemoPtNcs structure, an arbitrary point of which the spherical equivalents of abscissa and ordinate are to be determined. pPtX: Pointer to nemoPtNcs structure or NULL, returned coordinates on the abscissa great circle that is closest topPtY; ignored if NULL. pAX: Pointer to double or NULL, returnedpPtA-pPtXdistance as squared chord between the two points. pBX: As above,pPtX-pPtBdistance, ignored if NULL. pXY: Pointer to double or NULL, returned signed value. The absolute value is the chord squared of the abscissa (i.e.,pPtX-ptYdistance). The sign of the returned value indicates the handedness of thepPtA,pPtBandpPtY: it is positive if thepPtYis on the left-hand side of the directedpPtA-pPtBsegment, negative otherwise. Ignored if NULL.Return Value:Integer, error/status indicator. > 0 if the geometry is ill-defined (for instance, coincident or near-coincidentpPtAandpPtB), -1 ifpPtXis outsidepPtA-pPtBsegment onpPtBside, -2 ifpPtXis outsidepPtA-pPtBsegment onpPtAside, 0 otherwise.See Also:nemo_SphereSegsXsct()

nemo_SphereCircumcenter()

Synopsis:#include <nemo.h> int nemo_SphereSegsXsct(const nemoPtNcs *pPtA1, const nemoPtNcs *pPtA2, const nemoPtNcs *pPtB1, const nemoPtNcs *pPtB2, double cpCrit, nemoPtNcs *pPtX, int *ind);Description:Find point of intersection of two great circle segments on a unit sphere. The function recognizes that a point might be (near) coincident with another point, or that a point might be coincident with a line; the criterion is a point-to-point or point-to-line chord squared distance that is less than NEMO_FUZZ_SQDBL. The function also recognizes that two segment may be part of the same great circle ("co-planar segments").Arguments:pPtA1, pPtA2: Pointers to nemoPtNcs structures, first given great circle segment start and end point (segment "terminal points"). Note that the problem geometry becomes ill-defined if \the segment arc length is (neat) 0, and as it approaches π. For segments that define the great circle line used as a defining geometry element of a linear of area terrestrial object, an application should impose a conservative segment arc length restriction. pPtB1, pPtB2: Pointers to nemoPtNcs structures, second given great circle segment terminal points. cpCrit: Double, reserved for additional functionality. (NEMO_DOUBLE_UNDEF value assures future compatibility). pPtX: Pointer to nemoPtNcs structure, returned coordinates on the point of intersection of two great circle segments. When the point is (near) coincident with a terminal point of one of the segments, the point of intersection is considered to be the terminal point, when this is the a (near) coincident location of two terminal points, the intersection point is considered to be the terminal point of segment A. If the segments share a sub-segemnt, the returned value is undefined. iNd: Pointer to integer, returned additional common point or sub-segment information which the invoker might find to of use. (see below). ·Return Value:· Integer, error/status indicator. In general, if the value is: > 0 The geometry is ill-defined/unstable, no solution is possible = 0 There are no points in common to two great circle segments < 0 Two segments share either one common point or a sub-segment. · More specifically, if the returned value is: · > 1 Assertion error (unexpected, program logic error guard, or a violation of function's specifications). · = 1 One or both given segment has (near) zero length, no intersection computation is attempted. The invoker can determine which segment is the offending one by examiningiNdvalue returned. IfiNdis: = 1 First segment has (near) zero length. = 2 Second segment has (near) zero length. = 3 Both given segments have (near) zero length. · = 0 Two segments have no common points ("Normal Case" NO Intersection). If further details are required, the invoker must examineiNdvalue returned. IfiNdis: · = 0 The determination was based on proximity "quick-test", examining only the lenght of segments and distances between terminals.pPtXcoordinates are neither calculated nor returned. · = 1 Geometry evaluation was performed, planes of two segments were not found to be coincident, intersection point (pPtX) position was calculated and returned, but found to be outside of either (or both) given segments. Two segments form a right-handed system. =-1 As above, two segments form a left-handed system. · = 2 Segments were found to be co-planar, the determination was based on relative position of segment's terminals, and it was concluded that two segments share no common points. · = -1 Two segments have one common point, which might have been found either by intersection calculation or, in the case of co-planar segments, by analysis of the relative position of segment's terminals. IfiNdis: · abs(iNd) < 10: segments are not co-planar. abs(iNd) 2 to 5 (inclusive): intersection point on one segment line. · = 1pPtxis the intersection of two segments that are not co-planar, the intersection is not coincident with either segment terminal, and two segment form a right-handed system (i.e., rotation from directed segment A towards directed segment B of less than π is in the mathematically positive (counter-clockwise) direction). = -1 as above, but two ordered and directed segments form a left-handed system. · = 2 The intersection point is the start terminal of the A segment, "forking" from segment B, segments form a right-handed system. = -2 As above, segments form a left-handed system. = 3 The intersection point is the end terminal of the A segment, ("joining" the B segment). Assuming segment A extended in a straight line past its end terminal the segments would form a right-handed system. = -3 As above, two segments would form a left-handed system. = 4, -4, 5, -5 as above, with B segment forking off or joining A segment. The handedness of the A, B segment system is still defined using the same segment order (i.e., rotating from positive direction of A towards positive direction of B for less than π). · abs(iNd) 6 to 9 (inclusive): intersection point is common terminal. = 6, -6 common point is the starting terminal of both segments (i.e., two segments are "forking". The handedness of the system is as defined above. = 7, -7 common point is the end terminal of both systems (i.e., the two segments are joining), with handedness defined as above. = 8, -8 common point is the start terminal of A and end of B, with handedness defined as above. = 9, -9 as above, end terminal of A is start of B, with handedness defined as above. · > 9 segments are co-planar, therefore the handedness in undefined. There is only one terminal point shared by two segments, and that terminal is the point common to both segments. Even value of the indicator means segments have the same, and odd that segments have the opposite direction. Specifically: = 10 end of A is start of B. = -10 end of A is end of B. = 11 start of A is end of B. = -11 start of A is start of B. · In all of the above, when the calculated intersection point is near-coincident with the segment terminal, it is the terminal point that is considered to represent the location of the near-coincident point and is returned aspPtx. If the common point are near-coincident two terminals, the returned coordinates will be the terminal of segment A. · = -2 Segments are co-planar and share more than a single point, they share coincident or share a sub-segment of a finite length. IfiNd> 0, two given segments have the same direction along the shared sub-segment, if < 0, they have the opposite direction on the shared sub-segment. The shared sub-segment may start and/or end with a segment terminal point. · When two segments are coincident (i.e., they share both terminals). IfiNdis: = 1 start of A is start of B, end of A is end of B (same direction). = -1 start of A is end of B, end of A is start of B (opposite dir.). · When in addition to the sub-segment, two segments share one terminal point, ifiNdis: = 2 start of A is start of B, A is longer. = -2 start of A is end of B, A is longer. = 3 start of A is start of B, B is longer. = -3 start of A is end of B, B is longer. = 4 end of A is end of B, A is longer. = -4 end of A is start of B, A is longer. = 5 end of A is end of B, B is longer. = -5 end of A is start of B, B is longer. · When two segments share a sub-segment but not a terminal point, ifiNdis: = 6 B segment is inside A segment with the same direction. = -6 B segment is inside A segment with the opposite direction. = 7 A segment is inside B segment with the same direction. = -7 A segment is inside B segment with the opposite direction. = 8 B segment starts inside A segment and ends beyond it. = -8 B segment starts beyond A segment and ends in it. = 9 B segment starts below A segment and ends in it. = -9 B segment starts inside A segment and ends below it. ·See Also:nemo_SphereChordCoords()

nemo_SphereCircumcenter()