@@ -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+ float8 fpdist ;
660+ float8 spdist ;
661+
662+ if (spoint_at_sline (p , sl ))
663+ {
664+ return 0.0 ;
665+ }
666+
667+ sline_vector_begin (& v_beg , sl );
668+ sline_vector_end (& v_end , sl );
669+ spoint_vector3d (& v , p );
670+
671+ /* normal1 to the plane passing through the line and the center of the sphere */
672+ vector3d_cross (& normal1 , & v_beg , & v_end );
673+ if (vector3d_eq (& normal1 , & v ))
674+ {
675+ return PIH ;
676+ }
677+
678+ /* normal2 to the plane perpendicular to the given line. */
679+ vector3d_cross (& normal2 , & normal1 , & v );
680+ vector3d_cross (& line , & normal2 , & normal1 );
681+ norma = sqrt (line .x * line .x + line .y * line .y + line .z * line .z );
682+
683+ first_p .x = line .x / norma ;
684+ first_p .y = line .y / norma ;
685+ first_p .z = line .z / norma ;
686+ vector3d_spoint (& fp , & first_p );
687+
688+ if (spoint_at_sline (& fp , sl ))
689+ {
690+ return spoint_dist (& fp , p );
691+ }
692+
693+ vector3d_spoint (& fp , & v_beg );
694+ vector3d_spoint (& sp , & v_end );
695+ fpdist = spoint_dist (p , & fp );
696+ spdist = spoint_dist (p , & sp );
697+ return Min (fpdist , spdist );
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+ const SLine * s = (SLine * ) PG_GETARG_POINTER (0 );
1114+ const 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+ const SPoint * p = (SPoint * ) PG_GETARG_POINTER (0 );
1122+ const SLine * s = (SLine * ) PG_GETARG_POINTER (1 );
1123+ PG_RETURN_FLOAT8 (sline_point_dist (s , p ));
1124+ }
1125+
0 commit comments