@@ -33,6 +33,8 @@ PG_FUNCTION_INFO_V1(sphereline_overlap_neg);
3333PG_FUNCTION_INFO_V1 (spheretrans_from_line );
3434PG_FUNCTION_INFO_V1 (spheretrans_line );
3535PG_FUNCTION_INFO_V1 (spheretrans_line_inverse );
36+ PG_FUNCTION_INFO_V1 (sphereline_point_distance );
37+ PG_FUNCTION_INFO_V1 (sphereline_point_distance_com );
3638
3739/*
3840 * Swaps the beginning and ending of the line.
@@ -642,6 +644,59 @@ sline_center(SPoint *c, const SLine *sl)
642644 euler_spoint_trans (c , & p , & se );
643645}
644646
647+ float8 sline_point_dist (const SLine * sl , const SPoint * p )
648+ {
649+ Vector3D v_beg ;
650+ Vector3D v_end ;
651+ Vector3D v ;
652+ Vector3D normal1 ;
653+ Vector3D normal2 ;
654+ Vector3D line ;
655+ Vector3D first_p ;
656+ float8 norma ;
657+ SPoint fp ;
658+ SPoint sp ;
659+
660+ if (spoint_at_sline (p , sl ))
661+ {
662+ return 0.0 ;
663+ }
664+
665+ sline_vector_begin (& v_beg , sl );
666+ sline_vector_end (& v_end , sl );
667+ spoint_vector3d (& v , p );
668+
669+ /* normal1 to the plane passing through the line and the center of the sphere */
670+ vector3d_cross (& normal1 , & v_beg , & v_end );
671+ if (vector3d_eq (& normal1 , & v ))
672+ {
673+ return PIH ;
674+ }
675+
676+ /* normal2 to the plane perpendicular to the given line. */
677+ vector3d_cross (& normal2 , & normal1 , & v );
678+ vector3d_cross (& line , & normal2 , & normal1 );
679+ norma = sqrt (line .x * line .x + line .y * line .y + line .z * line .z );
680+
681+ first_p .x = line .x / norma ;
682+ first_p .y = line .y / norma ;
683+ first_p .z = line .z / norma ;
684+ vector3d_spoint (& fp , & first_p );
685+
686+ if (spoint_at_sline (& fp , sl ))
687+ {
688+ return spoint_dist (& fp , p );
689+ }
690+
691+ vector3d_spoint (& fp , & v_beg );
692+ vector3d_spoint (& sp , & v_end );
693+ if (FPle (spoint_dist (p , & fp ), spoint_dist (p , & sp )))
694+ {
695+ return spoint_dist (p , & fp );
696+ }
697+ return spoint_dist (p , & sp );
698+ }
699+
645700Datum
646701sphereline_in (PG_FUNCTION_ARGS )
647702{
@@ -1051,3 +1106,20 @@ spheretrans_from_line(PG_FUNCTION_ARGS)
10511106 sphereline_to_euler (e , l );
10521107 PG_RETURN_POINTER (e );
10531108}
1109+
1110+ Datum
1111+ sphereline_point_distance (PG_FUNCTION_ARGS )
1112+ {
1113+ SLine * s = (SLine * ) PG_GETARG_POINTER (0 );
1114+ SPoint * p = (SPoint * ) PG_GETARG_POINTER (1 );
1115+ PG_RETURN_FLOAT8 (sline_point_dist (s , p ));
1116+ }
1117+
1118+ Datum
1119+ sphereline_point_distance_com (PG_FUNCTION_ARGS )
1120+ {
1121+ SPoint * p = (SPoint * ) PG_GETARG_POINTER (0 );
1122+ SLine * s = (SLine * ) PG_GETARG_POINTER (1 );
1123+ PG_RETURN_FLOAT8 (sline_point_dist (s , p ));
1124+ }
1125+
0 commit comments