The following code is my attempt to find the intersection point in case of two splines. It is not the best method, There are a lot of limitations (see above). But I hope this gives you an idea. This code is for tests only, because of very limited testing.
ALink
--------
Public Sub Spline_Intersection_Sample()
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Setup important user-defined parameters:
'````````````````````````````````````````
'1) tolerance
Dim AbsTol As Double 'absolute tolerance in cm
AbsTol = 0.000001 ' <=== absolute deviation <= 0.01 mkm
'2) dimension of initial spline fragmentation
Dim N As Long
N = 100
'3) Upper limit for the quantity of iteration loops (for safety)
Dim ITERATIONS_MAX_LIMIT As Long
ITERATIONS_MAX_LIMIT = 1000
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Basic preparations
'Основные приготовления
'reference to Transient Geometry
'ссылка на вспомогательную геометрию
Dim oTG As TransientGeometry
Set oTG = ThisApplication.TransientGeometry
'reference to the 1st sketch (for simplicity)
'ссылка на первый эскиз
Dim oActiveSketch As PlanarSketch
Set oActiveSketch = ThisApplication.ActiveDocument. _
ComponentDefinition.Sketches.Item(1)
'reference to SketchPoints collection in oActiveSketch
'ссылка на коллекцию эскизных точек в активном эскизе
Dim oSketchPoints As SketchPoints
Set oSketchPoints = oActiveSketch.SketchPoints
'In this example we'll use two first splines.
'Be sure you have at least two splines.
'Здесь для простоты используем два первых сплайна эскиза
'Убедитесь, что в эскизе есть хотя бы два сплайна)
Dim oSpline1 As SketchSpline
Dim oSpline2 As SketchSpline
Set oSpline1 = oActiveSketch.SketchSplines(1)
Set oSpline2 = oActiveSketch.SketchSplines(2)
'evaluator of the first curve
'ссылка на вычислитель сплайна 1
Dim oCurve2dEvaluator1 As Curve2dEvaluator
Set oCurve2dEvaluator1 = oSpline1.Geometry.Evaluator
'evaluator of the second curve
'ссылка на вычислитель сплайна 2
Dim oCurve2dEvaluator2 As Curve2dEvaluator
Set oCurve2dEvaluator2 = oSpline2.Geometry.Evaluator
Dim Distance As Double
Dim oPoint2d1 As Point2d
Dim oPoint2d2 As Point2d
Dim IterationFact As Long
'call minimization procedure
Call FindIntersection_3( _
oCurve2dEvaluator1, _
oCurve2dEvaluator2, _
AbsTol, _
N, _
ITERATIONS_MAX_LIMIT, _
IterationFact, _
Distance, _
oPoint2d1, _
oPoint2d2)
'let us know if maximum iteration limit was exceeded
'possibly we have a problem
If IterationFact > ITERATIONS_MAX_LIMIT Then
MsgBox "Maximum iteration limit was exceeded." & vbNewLine _
& "Stopped at: " & IterationFact & " iterations"
End If
'ставим эскизную точку на кривой 1
'put sketch point on curve 1
Dim oP As SketchPoint
Set oP = oSketchPoints.Add(oPoint2d1, False)
MsgBox "Dist = " & Round(Distance * 10, 8) & " mm" & vbNewLine & _
"Iterations = " & IterationFact
End Sub 'Spline_Intersection_Sample
'
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
'
' FindIntersection_3
'
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Private Sub FindIntersection_3( _
ByRef oCurve2dEvaluator1 As Curve2dEvaluator, _
ByRef oCurve2dEvaluator2 As Curve2dEvaluator, _
ByVal AbsTol As Double, _
ByVal N As Long, _
ByVal ITERATIONS_MAX_LIMIT As Long, _
ByRef IterationFact As Long, _
ByRef Distance As Double, _
ByRef oPoint2d1 As Point2d, _
ByRef oPoint2d2 As Point2d)
'reference to Transient Geometry
'ссылка на вспомогательную геометрию
Dim oTG As TransientGeometry
Set oTG = ThisApplication.TransientGeometry
'parameter range for the 1st curve
'вычислим границы диапазона изменения параметра кривой 1
Dim Param1_Min As Double
Dim Param1_Max As Double
Call oCurve2dEvaluator1.GetParamExtents(Param1_Min, Param1_Max)
'parameter range for the 2nd curve
'вычислим границы диапазона изменения параметра кривой 2
Dim Param2_Min As Double
Dim Param2_Max As Double
Call oCurve2dEvaluator2.GetParamExtents(Param2_Min, Param2_Max)
'Step 1. A rough approximation for start points
'Шаг 1. Грубое начальное приближение для точки пересечения
Dim i As Long, j As Long
Dim x1 As Double
Dim x2 As Double
Dim y1 As Double
Dim y2 As Double
Dim dParams(0 To 0) As Double
Dim dPointsCoord() As Double
Dim Coord1() As Double
Dim Coord2() As Double
ReDim Coord1(0 To N, 1 To 2) 'arrays for coordinates
ReDim Coord2(0 To N, 1 To 2)
For i = 0 To N
dParams(0) = Param1_Min + i * (Param1_Max - Param1_Min) / N
Call oCurve2dEvaluator1.GetPointAtParam(dParams, dPointsCoord)
'запоминаем координаты точки i
'save coordinates for index i
Coord1(i, 1) = dPointsCoord(0)
Coord1(i, 2) = dPointsCoord(1)
Next i
For j = 0 To N
dParams(0) = Param2_Min + j * (Param2_Max - Param2_Min) / N
Call oCurve2dEvaluator2.GetPointAtParam(dParams, dPointsCoord)
'запоминаем координаты точки j
'save coordinates for index j
Coord2(j, 1) = dPointsCoord(0)
Coord2(j, 2) = dPointsCoord(1)
Next j
Dim Min As Double
Dim n1 As Long
Dim n2 As Long
Dim Dist As Double
Min = 1E+199: n1 = -1: n2 = -1 ' initial values
For i = 0 To N
For j = 0 To N
Dist = Sqr((Coord1(i, 1) - Coord2(j, 1)) ^ 2 + _
(Coord1(i, 2) - Coord2(j, 2)) ^ 2)
If Dist < Min Then
Min = Dist
n1 = i
n2 = j
End If
Next j
Next i
'Step 2. Find intersection point
'Шаг 2. Итерационный поиск точки пересечения
' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' %%%%%%%%%% Start %%%%%%%%%%
' %%%%%%%%%% Minimization %%%%%%%%%%
' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Dim p(0 To 8, 1 To 2) As Double 'cube vertex array
Dim D(0 To 8) As Double 'distances for each cube vertex
Dim Delta As Double 'cube size parameter
Dim IterCounter As Long 'loop counter
IterCounter = -1
'initial cube half size
Delta = (Param1_Max - Param1_Min + Param2_Max - Param2_Min) / N / 3
'cube center -- "vertex" #0
p(0, 1) = Param1_Min + n1 * (Param1_Max - Param1_Min) / N
p(0, 2) = Param2_Min + n2 * (Param2_Max - Param2_Min) / N
'~~~~~ Start Iterations ~~~~~
Do
IterCounter = IterCounter + 1 'iteration number
'vertex 1
p(1, 1) = p(0, 1) + Delta
p(1, 2) = p(0, 2)
'vertex 2
p(2, 1) = p(0, 1) + Delta
p(2, 2) = p(0, 2) + Delta
'vertex 3
p(3, 1) = p(0, 1)
p(3, 2) = p(0, 2) + Delta
'vertex 4
p(4, 1) = p(0, 1) - Delta
p(4, 2) = p(0, 2) + Delta
'vertex 5
p(5, 1) = p(0, 1) - Delta
p(5, 2) = p(0, 2)
'vertex 6
p(6, 1) = p(0, 1) - Delta
p(6, 2) = p(0, 2) - Delta
'vertex 7
p(7, 1) = p(0, 1)
p(7, 2) = p(0, 2) - Delta
'vertex 8
p(8, 1) = p(0, 1) + Delta
p(8, 2) = p(0, 2) - Delta
'Calculate distance for each cube vertex (#0..#8)
For i = 0 To 8
D(i) = CalcDistance(oCurve2dEvaluator1, oCurve2dEvaluator2, p(i, 1), p(i, 2))
Next i
'calc minimal distance
Min = D(0)
n1 = 0
For i = 1 To 8
If D(i) < Min Then
Min = D(i)
n1 = i
End If
Next i
'uncomment this line to see iterations in progress
' Debug.Print "Iter="; IterCounter, "Dist,(mm)= "; Min * 10#
If n1 = 0 Then
Delta = Delta * 0.7 'controls cube size
Else
p(0, 1) = p(n1, 1)
p(0, 2) = p(n1, 2)
End If
'move cube center to the vertex n1 (with min distance)
Loop Until (Min < AbsTol) Or (IterCounter > ITERATIONS_MAX_LIMIT)
'~~~~~~~~~~~~~~~~~~~~~~~~~~
'~~~~~ Stop iterations ~~~~
'~~~~~~~~~~~~~~~~~~~~~~~~~~
Distance = Min 'output
IterationFact = IterCounter 'output
'Calculate 1-st point coordinates
dParams(0) = p(0, 1)
Call oCurve2dEvaluator1.GetPointAtParam(dParams, dPointsCoord)
'создаем 2d точки для вызывающей процедуры
'create output 2d point for curve 1
Set oPoint2d1 = oTG.CreatePoint2d(dPointsCoord(0), dPointsCoord(1))
'Calculate 2-nd point coordinates
dParams(0) = p(0, 2)
Call oCurve2dEvaluator2.GetPointAtParam(dParams, dPointsCoord)
'создаем 2d точки для вызывающей процедуры
'create output 2d point for curve 2
Set oPoint2d2 = oTG.CreatePoint2d(dPointsCoord(0), dPointsCoord(1))
End Sub 'FindIntersection_3
'
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Private Function CalcDistance( _
ByRef oCurve2dEvaluator1 As Curve2dEvaluator, _
ByRef oCurve2dEvaluator2 As Curve2dEvaluator, _
ByVal param1 As Double, _
ByVal param2 As Double) As Double
Dim x1 As Double
Dim x2 As Double
Dim y1 As Double
Dim y2 As Double
Dim dParams(0 To 0) As Double
Dim dPointsCoord() As Double
'Calculate 1-st point coordinates (curve 1)
dParams(0) = param1
Call oCurve2dEvaluator1.GetPointAtParam(dParams, dPointsCoord)
x1 = dPointsCoord(0)
y1 = dPointsCoord(1)
'Calculate 2-nd point coordinates (curve 2)
dParams(0) = param2
Call oCurve2dEvaluator2.GetPointAtParam(dParams, dPointsCoord)
x2 = dPointsCoord(0)
y2 = dPointsCoord(1)
'distance between two points (cm)
CalcDistance = Sqr((x1 - x2) ^ 2 + (y1 - y2) ^ 2)
End Function 'CalcDistance
'
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Message was edited by: ALink