@@ -693,21 +693,23 @@ public double DistanceTo(Point3d p)
693
693
/// <summary>
694
694
/// Distance between two polyhedrons
695
695
/// </summary>
696
- public double DistanceTo_old ( ConvexPolyhedron cp )
696
+ /// <param name="c">Target polyhedron</param>
697
+ public double DistanceTo ( ConvexPolyhedron c )
697
698
{
698
- if ( this . Intersects ( cp ) )
699
- {
700
- return 0 ;
701
- }
702
- Point3d p1 , p2 ;
703
- return _distance_to_not_intersecting ( cp , out p1 , out p2 ) ;
699
+ Point3d c1 = new Point3d ( ) ;
700
+ Point3d c2 = new Point3d ( ) ;
701
+ return DistanceTo ( c , out c1 , out c2 ) ;
704
702
}
705
703
704
+
706
705
/// <summary>
707
706
/// Distance between two polyhedrons
707
+ /// <para> The output points are valid only in case of non-intersecting objects.</para>
708
708
/// </summary>
709
709
/// <param name="c">Target polyhedron</param>
710
- public double DistanceTo ( ConvexPolyhedron c )
710
+ /// <param name="point_on_this_cp">Closest point on this convex polyhedron</param>
711
+ /// <param name="point_on_target_cp">Closest point on target convex polyhedron</param>
712
+ public double DistanceTo ( ConvexPolyhedron c , out Point3d point_on_this_cp , out Point3d point_on_target_cp )
711
713
{
712
714
// Use "Method of Separating Axes" to test intersection combined with distance calculation
713
715
@@ -717,6 +719,10 @@ public double DistanceTo(ConvexPolyhedron c)
717
719
718
720
double dist = double . PositiveInfinity ;
719
721
bool intersecting = true ;
722
+ Point3d c1 = new Point3d ( ) ;
723
+ Point3d c2 = new Point3d ( ) ;
724
+ point_on_this_cp = c1 ;
725
+ point_on_target_cp = c2 ;
720
726
721
727
// Test faces of this CP for separation. Because of the counterclockwise ordering,
722
728
// the projection interval for this CP is (-inf, 0].
@@ -732,6 +738,7 @@ public double DistanceTo(ConvexPolyhedron c)
732
738
intersecting = false ;
733
739
double square_proj_dist = double . PositiveInfinity ;
734
740
Point3d best_proj_point = this . face [ i ] . Vertex [ 0 ] ;
741
+ Point3d target_point = this . face [ i ] . Vertex [ 0 ] ;
735
742
736
743
Plane3d plane = new Plane3d ( this . face [ i ] . Vertex [ 0 ] , this . face [ i ] . normal ) ;
737
744
foreach ( Point3d point in c . vertex )
@@ -742,6 +749,7 @@ public double DistanceTo(ConvexPolyhedron c)
742
749
{
743
750
square_proj_dist = tmp_dist ;
744
751
best_proj_point = projection ;
752
+ target_point = point ;
745
753
}
746
754
}
747
755
// test if best projection of c.vertex is inside the face
@@ -756,7 +764,7 @@ public double DistanceTo(ConvexPolyhedron c)
756
764
Vector3d v = new Vector3d ( this . face [ i ] . Vertex [ l ] , best_proj_point ) ;
757
765
if ( edge . Cross ( v ) . Dot ( this . face [ i ] . normal ) < 0 )
758
766
{
759
- // projection ourside of face
767
+ // projection outside of face
760
768
inside = false ;
761
769
break ;
762
770
}
@@ -765,7 +773,11 @@ public double DistanceTo(ConvexPolyhedron c)
765
773
if ( inside )
766
774
{
767
775
double tmp_dist = Math . Sqrt ( square_proj_dist ) ;
768
- if ( tmp_dist < dist ) { dist = tmp_dist ; }
776
+ if ( tmp_dist < dist ) {
777
+ dist = tmp_dist ;
778
+ point_on_this_cp = best_proj_point ;
779
+ point_on_target_cp = target_point ;
780
+ }
769
781
}
770
782
}
771
783
}
@@ -784,6 +796,7 @@ public double DistanceTo(ConvexPolyhedron c)
784
796
intersecting = false ;
785
797
double square_proj_dist = double . PositiveInfinity ;
786
798
Point3d best_proj_point = c . face [ i ] . Vertex [ 0 ] ;
799
+ Point3d target_point = c . face [ i ] . Vertex [ 0 ] ;
787
800
788
801
Plane3d plane = new Plane3d ( c . face [ i ] . Vertex [ 0 ] , c . face [ i ] . normal ) ;
789
802
foreach ( Point3d point in this . vertex )
@@ -794,6 +807,7 @@ public double DistanceTo(ConvexPolyhedron c)
794
807
{
795
808
square_proj_dist = tmp_dist ;
796
809
best_proj_point = projection ;
810
+ target_point = point ;
797
811
}
798
812
}
799
813
// test if best projection of c.vertex is inside the face
@@ -808,7 +822,7 @@ public double DistanceTo(ConvexPolyhedron c)
808
822
Vector3d v = new Vector3d ( c . face [ i ] . Vertex [ l ] , best_proj_point ) ;
809
823
if ( edge . Cross ( v ) . Dot ( c . face [ i ] . normal ) < 0 )
810
824
{
811
- // projection ourside of face
825
+ // projection outside of face
812
826
inside = false ;
813
827
break ;
814
828
}
@@ -817,7 +831,12 @@ public double DistanceTo(ConvexPolyhedron c)
817
831
if ( inside )
818
832
{
819
833
double tmp_dist = Math . Sqrt ( square_proj_dist ) ;
820
- if ( tmp_dist < dist ) { dist = tmp_dist ; }
834
+ if ( tmp_dist < dist )
835
+ {
836
+ dist = tmp_dist ;
837
+ point_on_this_cp = best_proj_point ;
838
+ point_on_target_cp = target_point ;
839
+ }
821
840
}
822
841
823
842
}
@@ -854,8 +873,13 @@ public double DistanceTo(ConvexPolyhedron c)
854
873
{
855
874
// The projections of this CP and 'c' onto the line P + t * N are on opposite sides of the projection of P.
856
875
intersecting = false ;
857
- double tmp_dist = s1 . DistanceTo ( s2 ) ;
858
- if ( tmp_dist < dist ) { dist = tmp_dist ; }
876
+ double tmp_dist = s1 . DistanceTo ( s2 , out c1 , out c2 ) ;
877
+ if ( tmp_dist < dist )
878
+ {
879
+ dist = tmp_dist ;
880
+ point_on_this_cp = c1 ;
881
+ point_on_target_cp = c2 ;
882
+ }
859
883
}
860
884
}
861
885
}
@@ -871,115 +895,6 @@ public double DistanceTo(ConvexPolyhedron c)
871
895
}
872
896
}
873
897
874
- /// <summary>
875
- /// Distance between two polyhedrons
876
- /// <para> The output points may be not unique in case of intersecting objects.</para>
877
- /// </summary>
878
- /// <param name="cp">Target polyhedron</param>
879
- /// <param name="point_on_this_cp">Closest point on this convex polyhedron</param>
880
- /// <param name="point_on_target_cp">Closest point on target convex polyhedron</param>
881
- public double DistanceTo ( ConvexPolyhedron cp , out Point3d point_on_this_cp , out Point3d point_on_target_cp )
882
- {
883
- if ( this . Intersects ( cp ) )
884
- {
885
- // check if one CP is inside other CP
886
- Point3d c1 = this . Center ;
887
- point_on_this_cp = c1 ;
888
- point_on_target_cp = c1 ;
889
- if ( c1 . BelongsTo ( cp ) )
890
- {
891
- return 0 ;
892
- }
893
- Point3d c2 = cp . Center ;
894
- if ( c2 . BelongsTo ( this ) )
895
- {
896
- point_on_this_cp = c2 ;
897
- point_on_target_cp = c2 ;
898
- return 0 ;
899
- }
900
-
901
- // If CPs are partially intersecting, return any common point
902
- Point3d common_point = _get_common_point ( cp ) ;
903
- if ( common_point != null )
904
- {
905
- point_on_this_cp = common_point ;
906
- point_on_target_cp = common_point ;
907
- return 0 ;
908
- }
909
- }
910
-
911
- return _distance_to_not_intersecting ( cp , out point_on_this_cp , out point_on_target_cp ) ;
912
- }
913
-
914
- internal double _distance_to_not_intersecting ( ConvexPolyhedron cp , out Point3d point_on_this_cp , out Point3d point_on_target_cp )
915
- {
916
- double dist = double . PositiveInfinity ;
917
- Point3d c1 = new Point3d ( ) ;
918
- Point3d c2 = new Point3d ( ) ;
919
- point_on_this_cp = c1 ;
920
- point_on_target_cp = c1 ;
921
-
922
- // test vertices of this cp
923
- for ( int i = 0 ; i < numVertices ; i ++ )
924
- {
925
- for ( int k = 0 ; k < cp . numFaces ; k ++ )
926
- {
927
- for ( int l = 0 ; l < cp . face [ k ] . vertex . Length - 2 ; l ++ )
928
- {
929
- Triangle t2 = new Triangle ( cp . face [ k ] . Vertex [ 0 ] , cp . face [ k ] . Vertex [ l + 1 ] , cp . face [ k ] . Vertex [ l + 2 ] ) ;
930
-
931
- double tmp_dist = vertex [ i ] . DistanceTo ( t2 , out c1 ) ;
932
- if ( tmp_dist < dist )
933
- {
934
- point_on_this_cp = vertex [ i ] ;
935
- point_on_target_cp = c1 ;
936
- dist = tmp_dist ;
937
- }
938
- }
939
-
940
- }
941
- }
942
-
943
- // test vertices of target cp
944
- for ( int i = 0 ; i < cp . numVertices ; i ++ )
945
- {
946
- for ( int k = 0 ; k < this . numFaces ; k ++ )
947
- {
948
- for ( int l = 0 ; l < this . face [ k ] . vertex . Length - 2 ; l ++ )
949
- {
950
- Triangle t2 = new Triangle ( this . face [ k ] . Vertex [ 0 ] , this . face [ k ] . Vertex [ l + 1 ] , this . face [ k ] . Vertex [ l + 2 ] ) ;
951
-
952
- double tmp_dist = cp . vertex [ i ] . DistanceTo ( t2 , out c1 ) ;
953
- if ( tmp_dist < dist )
954
- {
955
- point_on_this_cp = c1 ;
956
- point_on_target_cp = cp . vertex [ i ] ;
957
- dist = tmp_dist ;
958
- }
959
- }
960
-
961
- }
962
- }
963
-
964
- // test edges
965
- for ( int i = 0 ; i < this . numEdges ; i ++ )
966
- {
967
- Segment3d s1 = new Segment3d ( this . vertex [ this . edge [ i ] . p1 ] , this . vertex [ this . edge [ i ] . p2 ] ) ;
968
- for ( int j = 0 ; j < cp . numEdges ; j ++ )
969
- {
970
- Segment3d s2 = new Segment3d ( cp . vertex [ cp . edge [ j ] . p1 ] , cp . vertex [ cp . edge [ j ] . p2 ] ) ;
971
- double tmp_dist = s1 . DistanceTo ( s2 , out c1 , out c2 ) ;
972
- if ( tmp_dist < dist )
973
- {
974
- point_on_this_cp = c1 ;
975
- point_on_target_cp = c2 ;
976
- dist = tmp_dist ;
977
- }
978
- }
979
- }
980
-
981
- return dist ;
982
- }
983
898
984
899
internal Point3d _get_common_point ( ConvexPolyhedron cp )
985
900
{
0 commit comments