149 lines
5.9 KiB
VB.net
149 lines
5.9 KiB
VB.net
Module Module1
|
|
|
|
Class Triangle
|
|
Property P1 As Tuple(Of Double, Double)
|
|
Property P2 As Tuple(Of Double, Double)
|
|
Property P3 As Tuple(Of Double, Double)
|
|
|
|
Sub New(p1 As Tuple(Of Double, Double), p2 As Tuple(Of Double, Double), p3 As Tuple(Of Double, Double))
|
|
Me.P1 = p1
|
|
Me.P2 = p2
|
|
Me.P3 = p3
|
|
End Sub
|
|
|
|
Function Det2D() As Double
|
|
Return P1.Item1 * (P2.Item2 - P3.Item2) +
|
|
P2.Item1 * (P3.Item2 - P1.Item2) +
|
|
P3.Item1 * (P1.Item2 - P2.Item2)
|
|
End Function
|
|
|
|
Sub CheckTriWinding(allowReversed As Boolean)
|
|
Dim detTri = Det2D()
|
|
If detTri < 0.0 Then
|
|
If allowReversed Then
|
|
Dim a = P3
|
|
P3 = P2
|
|
P2 = a
|
|
Else
|
|
Throw New Exception("Triangle has wrong winding direction")
|
|
End If
|
|
End If
|
|
End Sub
|
|
|
|
Function BoundaryCollideChk(eps As Double) As Boolean
|
|
Return Det2D() < eps
|
|
End Function
|
|
|
|
Function BoundaryDoesntCollideChk(eps As Double) As Boolean
|
|
Return Det2D() <= eps
|
|
End Function
|
|
|
|
Public Overrides Function ToString() As String
|
|
Return String.Format("Triangle: {0}, {1}, {2}", P1, P2, P3)
|
|
End Function
|
|
End Class
|
|
|
|
Function TriTri2D(t1 As Triangle, t2 As Triangle, Optional eps As Double = 0.0, Optional alloweReversed As Boolean = False, Optional onBoundary As Boolean = True) As Boolean
|
|
'Triangles must be expressed anti-clockwise
|
|
t1.CheckTriWinding(alloweReversed)
|
|
t2.CheckTriWinding(alloweReversed)
|
|
|
|
'"onboundary" determines whether points on boundary are considered as colliding or not
|
|
Dim chkEdge = If(onBoundary, Function(t As Triangle) t.BoundaryCollideChk(eps), Function(t As Triangle) t.BoundaryDoesntCollideChk(eps))
|
|
Dim lp1 As New List(Of Tuple(Of Double, Double)) From {t1.P1, t1.P2, t1.P3}
|
|
Dim lp2 As New List(Of Tuple(Of Double, Double)) From {t2.P1, t2.P2, t2.P3}
|
|
|
|
'for each edge E of t1
|
|
For i = 0 To 2
|
|
Dim j = (i + 1) Mod 3
|
|
'Check all points of t2 lay on the external side of edge E.
|
|
'If they do, the triangles do not overlap.
|
|
If chkEdge(New Triangle(lp1(i), lp1(j), lp2(0))) AndAlso
|
|
chkEdge(New Triangle(lp1(i), lp1(j), lp2(1))) AndAlso
|
|
chkEdge(New Triangle(lp1(i), lp1(j), lp2(2))) Then
|
|
Return False
|
|
End If
|
|
Next
|
|
|
|
'for each edge E of t2
|
|
For i = 0 To 2
|
|
Dim j = (i + 1) Mod 3
|
|
'Check all points of t1 lay on the external side of edge E.
|
|
'If they do, the triangles do not overlap.
|
|
If chkEdge(New Triangle(lp2(i), lp2(j), lp1(0))) AndAlso
|
|
chkEdge(New Triangle(lp2(i), lp2(j), lp1(1))) AndAlso
|
|
chkEdge(New Triangle(lp2(i), lp2(j), lp1(2))) Then
|
|
Return False
|
|
End If
|
|
Next
|
|
|
|
'The triangles overlap
|
|
Return True
|
|
End Function
|
|
|
|
Sub Overlap(t1 As Triangle, t2 As Triangle, Optional eps As Double = 0.0, Optional allowReversed As Boolean = False, Optional onBoundary As Boolean = True)
|
|
If TriTri2D(t1, t2, eps, allowReversed, onBoundary) Then
|
|
Console.WriteLine("overlap")
|
|
Else
|
|
Console.WriteLine("do not overlap")
|
|
End If
|
|
End Sub
|
|
|
|
Sub Main()
|
|
Dim t1 = New Triangle(Tuple.Create(0.0, 0.0), Tuple.Create(5.0, 0.0), Tuple.Create(0.0, 5.0))
|
|
Dim t2 = New Triangle(Tuple.Create(0.0, 0.0), Tuple.Create(5.0, 0.0), Tuple.Create(0.0, 6.0))
|
|
Console.WriteLine("{0} and", t1)
|
|
Console.WriteLine("{0}", t2)
|
|
Overlap(t1, t2)
|
|
Console.WriteLine()
|
|
|
|
' need to allow reversed for this pair to avoid exception
|
|
t1 = New Triangle(Tuple.Create(0.0, 0.0), Tuple.Create(0.0, 5.0), Tuple.Create(5.0, 0.0))
|
|
t2 = t1
|
|
Console.WriteLine("{0} and", t1)
|
|
Console.WriteLine("{0}", t2)
|
|
Overlap(t1, t2, 0.0, True)
|
|
Console.WriteLine()
|
|
|
|
t1 = New Triangle(Tuple.Create(0.0, 0.0), Tuple.Create(5.0, 0.0), Tuple.Create(0.0, 5.0))
|
|
t2 = New Triangle(Tuple.Create(-10.0, 0.0), Tuple.Create(-5.0, 0.0), Tuple.Create(-1.0, 6.0))
|
|
Console.WriteLine("{0} and", t1)
|
|
Console.WriteLine("{0}", t2)
|
|
Overlap(t1, t2)
|
|
Console.WriteLine()
|
|
|
|
t1.P3 = Tuple.Create(2.5, 5.0)
|
|
t2 = New Triangle(Tuple.Create(0.0, 4.0), Tuple.Create(2.5, -1.0), Tuple.Create(5.0, 4.0))
|
|
Console.WriteLine("{0} and", t1)
|
|
Console.WriteLine("{0}", t2)
|
|
Overlap(t1, t2)
|
|
Console.WriteLine()
|
|
|
|
t1 = New Triangle(Tuple.Create(0.0, 0.0), Tuple.Create(1.0, 1.0), Tuple.Create(0.0, 2.0))
|
|
t2 = New Triangle(Tuple.Create(2.0, 1.0), Tuple.Create(3.0, 0.0), Tuple.Create(3.0, 2.0))
|
|
Console.WriteLine("{0} and", t1)
|
|
Console.WriteLine("{0}", t2)
|
|
Overlap(t1, t2)
|
|
Console.WriteLine()
|
|
|
|
t2 = New Triangle(Tuple.Create(2.0, 1.0), Tuple.Create(3.0, -2.0), Tuple.Create(3.0, 4.0))
|
|
Console.WriteLine("{0} and", t1)
|
|
Console.WriteLine("{0}", t2)
|
|
Overlap(t1, t2)
|
|
Console.WriteLine()
|
|
|
|
t1 = New Triangle(Tuple.Create(0.0, 0.0), Tuple.Create(1.0, 0.0), Tuple.Create(0.0, 1.0))
|
|
t2 = New Triangle(Tuple.Create(1.0, 0.0), Tuple.Create(2.0, 0.0), Tuple.Create(1.0, 1.1))
|
|
Console.WriteLine("{0} and", t1)
|
|
Console.WriteLine("{0}", t2)
|
|
Console.WriteLine("which have only a single corner in contact, if boundary points collide")
|
|
Overlap(t1, t2)
|
|
Console.WriteLine()
|
|
|
|
Console.WriteLine("{0} and", t1)
|
|
Console.WriteLine("{0}", t2)
|
|
Console.WriteLine("which have only a single corner in contact, if boundary points do not collide")
|
|
Overlap(t1, t2, 0.0, False, False)
|
|
End Sub
|
|
|
|
End Module
|