@@ -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)
642644euler_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)
10511106sphereline_to_euler (e ,l );
10521107PG_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+