Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Module Module1
- Public Class Misc
- 'Chained comparison function
- Public Shared Function CCOMP(Of T)(ParamArray ByVal item() As T) As Boolean
- Dim Prev As T = Nothing
- For Each I As T In item
- If Prev IsNot Nothing Then If Not I.Equals(Prev) Then Return False
- Prev = I
- Next
- Return True
- End Function
- End Class
- Public Structure XDecimal
- Public Shared Zero As New XDecimal(0D)
- Public Shared NegativeOne As New XDecimal(-1D)
- Private ReadOnly State As States
- Private ReadOnly Value As Decimal
- Public Enum States
- NaN
- Number
- Undefined
- End Enum
- Public Sub New(Value As Decimal)
- State = States.Number
- Me.Value = Value
- End Sub
- Public Sub New(State As States)
- Me.State = State
- End Sub
- Public Overrides Function ToString() As String
- If State = States.Number Then Return Value.ToString
- Return State.ToString
- End Function
- Public Shared Narrowing Operator CType(ByVal Dec As Decimal) As XDecimal
- Return New XDecimal(Dec)
- End Operator
- Public Shared Operator =(XDec1 As XDecimal, XDec2 As XDecimal) As Boolean
- If XDec1.State = XDec2.State Then
- If XDec1.State = States.Number Then Return XDec1.Value = XDec2.Value Else Return False
- End If
- Return False
- End Operator
- Public Shared Operator =(XDec As XDecimal, State As States) As Boolean
- Return XDec.State = State
- End Operator
- Public Shared Operator <>(XDec1 As XDecimal, XDec2 As XDecimal) As Boolean
- If XDec1.State = XDec2.State Then
- If XDec1.State = States.Number Then Return XDec1.Value = XDec2.Value Else Return True
- End If
- Return True
- End Operator
- Public Shared Operator <>(XDec As XDecimal, State As States) As Boolean
- Return XDec.State <> State
- End Operator
- Public Shared Operator *(XDec1 As XDecimal, XDec2 As XDecimal) As XDecimal
- If XDec1.State = States.Number AndAlso XDec2.State = States.Number Then Return New XDecimal(XDec1.Value * XDec2.Value)
- If XDec1.State = States.NaN OrElse XDec2.State = States.NaN Then Return New XDecimal(States.NaN)
- Return New XDecimal(States.Undefined)
- End Operator
- Public Shared Operator /(XDec1 As XDecimal, XDec2 As XDecimal) As XDecimal
- If XDec1.State = States.Number AndAlso XDec2.State = States.Number Then
- If XDec2.Value = 0D Then Return New XDecimal(States.Undefined)
- Return New XDecimal(XDec1.Value / XDec2.Value)
- End If
- If XDec1.State = States.NaN OrElse XDec2.State = States.NaN Then Return New XDecimal(States.NaN)
- Return New XDecimal(States.Undefined)
- End Operator
- Public Shared Operator +(XDec1 As XDecimal, XDec2 As XDecimal) As XDecimal
- If XDec1.State = States.Number AndAlso XDec2.State = States.Number Then Return New XDecimal(XDec1.Value + XDec2.Value)
- If XDec1.State = States.NaN OrElse XDec2.State = States.NaN Then Return New XDecimal(States.NaN)
- Return New XDecimal(States.Undefined)
- End Operator
- Public Shared Operator -(XDec1 As XDecimal, XDec2 As XDecimal) As XDecimal
- If XDec1.State = States.Number AndAlso XDec2.State = States.Number Then Return New XDecimal(XDec1.Value - XDec2.Value)
- If XDec1.State = States.NaN OrElse XDec2.State = States.NaN Then Return New XDecimal(States.NaN)
- Return New XDecimal(States.Undefined)
- End Operator
- Public Shared Operator <(XDec1 As XDecimal, XDec2 As XDecimal) As Boolean
- If XDec1.State = States.Number AndAlso XDec2.State = States.Number Then Return XDec1.Value < XDec2.Value
- Return False
- End Operator
- Public Shared Operator >(XDec1 As XDecimal, XDec2 As XDecimal) As Boolean
- If XDec1.State = States.Number AndAlso XDec2.State = States.Number Then Return XDec1.Value > XDec2.Value
- Return False
- End Operator
- Public Shared Operator >=(XDec1 As XDecimal, XDec2 As XDecimal) As Boolean
- If XDec1.State = States.Number AndAlso XDec2.State = States.Number Then Return XDec1.Value >= XDec2.Value
- Return False
- End Operator
- Public Shared Operator <=(XDec1 As XDecimal, XDec2 As XDecimal) As Boolean
- If XDec1.State = States.Number AndAlso XDec2.State = States.Number Then Return XDec1.Value <= XDec2.Value
- Return False
- End Operator
- End Structure
- Public Structure Point
- Public ReadOnly X As XDecimal
- Public ReadOnly Y As XDecimal
- Public Sub New(ByVal X As XDecimal, ByVal Y As XDecimal)
- Me.X = X
- Me.Y = Y
- End Sub
- End Structure
- Public Structure Line
- Public ReadOnly P1 As Point
- Public ReadOnly P2 As Point
- Public ReadOnly Slope As XDecimal
- Public ReadOnly Yintercept As XDecimal
- Public ReadOnly Xintercept As XDecimal
- Public ReadOnly IsVerticalLine As Boolean
- Public ReadOnly IsHorizontalLine As Boolean
- Public Sub New(ByVal X1 As XDecimal, ByVal Y1 As XDecimal, ByVal X2 As XDecimal, ByVal Y2 As XDecimal)
- P1 = New Point(X1, Y1)
- P2 = New Point(X2, Y2)
- Slope = (P2.Y - P1.Y) / (P2.X - P1.X)
- If Slope = XDecimal.Zero Then
- IsVerticalLine = False
- IsHorizontalLine = True
- Xintercept = XDecimal.States.Undefined
- Yintercept = P1.Y
- ElseIf Slope = XDecimal.States.Undefined Then
- IsVerticalLine = True
- IsHorizontalLine = False
- Yintercept = XDecimal.States.Undefined
- Xintercept = P1.X
- Else
- Yintercept = P1.Y - (P1.X * Slope)
- Xintercept = (Yintercept * XDecimal.NegativeOne) / Slope
- End If
- End Sub
- Public Sub New(ByVal P1 As Point, ByVal P2 As Point)
- Me.P1 = P1
- Me.P2 = P2
- Slope = (P2.Y - P1.Y) / (P2.X - P1.X)
- If Slope = XDecimal.Zero Then
- IsVerticalLine = False
- IsHorizontalLine = True
- Xintercept = XDecimal.States.Undefined
- Yintercept = P1.Y
- ElseIf Slope = XDecimal.States.Undefined Then
- IsVerticalLine = True
- IsHorizontalLine = False
- Yintercept = XDecimal.States.Undefined
- Xintercept = P1.X
- Else
- Yintercept = P1.Y - (P1.X * Slope)
- Xintercept = (Yintercept * XDecimal.NegativeOne) / Slope
- End If
- End Sub
- 'Line Intersects Point
- Public Function Intersects(ByVal Point As Point) As Boolean
- If Slope = XDecimal.States.Undefined Then Return Point.X = P1.X
- If Slope = XDecimal.Zero Then Return Point.Y = P1.Y
- If (Point.X * Slope) + Yintercept = Point.Y Then Return True
- Return False
- End Function
- 'Line Intersects Line
- Public Function Intersects(ByVal Line As Line) As Boolean
- If Slope = Line.Slope Then Return P1.Y = Line.P1.Y
- If Slope = XDecimal.States.Undefined AndAlso Line.Slope = XDecimal.States.Undefined Then Return P1.X = Line.P1.X
- Return True
- End Function
- Public Shared Function GetSlope(ByVal X1 As XDecimal, ByVal Y1 As XDecimal, ByVal X2 As XDecimal, ByVal Y2 As XDecimal) As XDecimal
- Return (Y2 - Y1) / (X2 - X1)
- End Function
- Public Shared Function GetYintercept(ByVal X1 As XDecimal, ByVal Y1 As XDecimal, ByVal X2 As XDecimal, ByVal Y2 As XDecimal) As XDecimal
- Dim Slope As XDecimal = GetSlope(X1, Y1, X2, Y2)
- Return Y1 - (X1 * Slope)
- End Function
- Public Shared Function GetXintercept(ByVal X1 As XDecimal, ByVal Y1 As XDecimal, ByVal X2 As XDecimal, ByVal Y2 As XDecimal) As XDecimal
- Dim Slope As XDecimal = GetSlope(X1, Y1, X2, Y2)
- Dim Yintercept As XDecimal = Y1 - (X1 * Slope)
- Return (Yintercept * -1) / Slope
- End Function
- End Structure
- Public Structure LineSegment
- Public ReadOnly P1 As Point
- Public ReadOnly P2 As Point
- Public ReadOnly Slope As XDecimal
- Public ReadOnly Yintercept As XDecimal
- Public ReadOnly Xintercept As XDecimal
- Public ReadOnly IsVerticalLineSegment As Boolean
- Public ReadOnly IsHorizontalLineSegment As Boolean
- Public Sub New(ByVal X1 As XDecimal, ByVal Y1 As XDecimal, ByVal X2 As XDecimal, ByVal Y2 As XDecimal)
- P1 = New Point(X1, Y1)
- P2 = New Point(X2, Y2)
- Slope = (P2.Y - P1.Y) / (P2.X - P1.X)
- If Slope = XDecimal.Zero Then
- IsVerticalLineSegment = False
- IsHorizontalLineSegment = True
- Xintercept = XDecimal.States.Undefined
- If (P1.X <= XDecimal.Zero AndAlso P2.X >= XDecimal.Zero) _
- OrElse (P2.X <= XDecimal.Zero AndAlso P1.X >= XDecimal.Zero) _
- Then Yintercept = P1.Y Else Yintercept = XDecimal.States.Undefined
- ElseIf Slope = XDecimal.States.Undefined Then
- IsVerticalLineSegment = True
- IsHorizontalLineSegment = False
- Yintercept = XDecimal.States.Undefined
- If (P1.Y >= XDecimal.Zero AndAlso P2.Y <= XDecimal.Zero) _
- OrElse (P2.Y <= XDecimal.Zero AndAlso P1.Y >= XDecimal.Zero) _
- Then Xintercept = P1.X _
- Else Xintercept = XDecimal.States.Undefined
- Else
- If (P1.X <= XDecimal.Zero AndAlso P2.X >= XDecimal.Zero) _
- OrElse (P2.X <= XDecimal.Zero AndAlso P1.X >= XDecimal.Zero) _
- Then Yintercept = P1.Y - (P1.X * Slope) _
- Else Yintercept = XDecimal.States.Undefined
- If (P1.Y >= XDecimal.Zero AndAlso P2.Y <= XDecimal.Zero) _
- OrElse (P2.Y <= XDecimal.Zero AndAlso P1.Y >= XDecimal.Zero) _
- Then Xintercept = (Yintercept * XDecimal.NegativeOne) / Slope _
- Else Xintercept = XDecimal.States.Undefined
- End If
- End Sub
- Public Sub New(ByVal P1 As Point, ByVal P2 As Point)
- Me.P1 = P1
- Me.P2 = P2
- Slope = (P2.Y - P1.Y) / (P2.X - P1.X)
- If Slope = XDecimal.Zero Then
- IsVerticalLineSegment = False
- IsHorizontalLineSegment = True
- Xintercept = XDecimal.States.Undefined
- If (P1.X <= XDecimal.Zero AndAlso P2.X >= XDecimal.Zero) _
- OrElse (P2.X <= XDecimal.Zero AndAlso P1.X >= XDecimal.Zero) _
- Then Yintercept = P1.Y Else Yintercept = XDecimal.States.Undefined
- ElseIf Slope = XDecimal.States.Undefined Then
- IsVerticalLineSegment = True
- IsHorizontalLineSegment = False
- Yintercept = XDecimal.States.Undefined
- If (P1.Y >= XDecimal.Zero AndAlso P2.Y <= XDecimal.Zero) _
- OrElse (P2.Y <= XDecimal.Zero AndAlso P1.Y >= XDecimal.Zero) _
- Then Xintercept = P1.X _
- Else Xintercept = XDecimal.States.Undefined
- Else
- If (P1.X <= XDecimal.Zero AndAlso P2.X >= XDecimal.Zero) _
- OrElse (P2.X <= XDecimal.Zero AndAlso P1.X >= XDecimal.Zero) _
- Then Yintercept = P1.Y - (P1.X * Slope) _
- Else Yintercept = XDecimal.States.Undefined
- If (P1.Y >= XDecimal.Zero AndAlso P2.Y <= XDecimal.Zero) _
- OrElse (P2.Y <= XDecimal.Zero AndAlso P1.Y >= XDecimal.Zero) _
- Then Xintercept = (Yintercept * XDecimal.NegativeOne) / Slope _
- Else Xintercept = XDecimal.States.Undefined
- End If
- End Sub
- 'LineSegment Intersects Point
- Public Function Intersects(ByVal Point As Point) As Boolean
- If (Point.X >= P1.X AndAlso Point.X <= P2.X) _
- OrElse (Point.X >= P2.X AndAlso Point.X <= P1.X) _
- Then Return (Point.X * Slope) + Yintercept = Point.Y
- Return False
- End Function
- 'LineSegment Intersects Line
- Public Function Intersects(ByVal Line As Line) As Boolean
- If Slope = XDecimal.States.Undefined Then
- If Line.Slope = XDecimal.States.Undefined Then Return P1.X = Line.P1.X
- Return Intersects(New Point(P1.X, (P1.X * Line.Slope) + Line.Yintercept))
- ElseIf Slope = Line.Slope Then
- Return Line.Intersects(New Point(P1.X, P1.Y))
- Else
- Dim X1 As XDecimal = (Line.Slope * P1.X) + Line.Yintercept
- Dim X2 As XDecimal = (Line.Slope * P2.X) + Line.Yintercept
- If X1 <= P1.X Then Return X2 >= P2.X Else If X1 >= P1.X Then Return X2 <= P2.X
- End If
- Return False
- End Function
- 'LineSegment Intersects LineSegment
- Public Function Intersects(ByVal LineSegment As LineSegment) As Boolean
- If Slope = XDecimal.States.Undefined Then
- If LineSegment.Slope = XDecimal.States.Undefined Then
- If P1.X = LineSegment.P1.X Then
- If (P1.Y >= LineSegment.P1.Y AndAlso P2.Y <= LineSegment.P1.Y) _
- OrElse (P1.Y <= LineSegment.P1.Y AndAlso P2.Y >= LineSegment.P1.Y) _
- Then Return True
- End If
- Return False
- Else
- Dim L As New Line(LineSegment.P1, LineSegment.P2)
- Return LineSegment.Intersects(New Point(P1.X, (P1.X * L.Slope) + L.Yintercept))
- End If
- Else
- If LineSegment.Slope = XDecimal.States.Undefined Then
- Dim L As New Line(P1, P2)
- Return Intersects(New Point(LineSegment.P1.X, (LineSegment.P1.X * L.Slope) + L.Yintercept))
- Else
- Dim L1 As New Line(P1, P2)
- Dim L2 As New Line(LineSegment.P1, LineSegment.P2)
- Dim X As XDecimal = (L2.Yintercept - L1.Yintercept) / (L1.Slope - L2.Slope)
- If (X >= L1.P1.X AndAlso X <= L1.P2.X) OrElse (X <= L1.P1.X AndAlso X >= L1.P2.X) Then Return True
- End If
- End If
- Return False
- End Function
- Public Shared Function GetSlope(ByVal X1 As XDecimal, ByVal Y1 As XDecimal, ByVal X2 As XDecimal, ByVal Y2 As XDecimal) As XDecimal
- Return (Y2 - Y1) / (X2 - X1)
- End Function
- End Structure
- Private Structure Circle
- Public X As XDecimal
- Public Y As XDecimal
- Public Radius As XDecimal
- Public Sub New(ByVal X As XDecimal, ByVal Y As XDecimal, ByVal Radius As XDecimal)
- Me.X = X
- Me.Y = Y
- Me.Radius = Radius
- End Sub
- Public Function ContainsPoint(ByVal Point As Point) As Boolean
- Dim _X As XDecimal = Point.X - X
- _X *= _X
- Dim _Y As XDecimal = Point.Y - Y
- _Y *= _Y
- If _X + _Y <= Radius * Radius Then Return True
- Return False
- End Function
- Public Function Intersects(ByVal Line As Line) As Boolean
- End Function
- Public Function Intersects(ByVal LineSegment As LineSegment) As Boolean
- End Function
- Public Function Intersects(ByVal Circle As Circle) As Boolean
- Dim _X As XDecimal = Circle.X - X
- _X *= _X
- Dim _Y As XDecimal = Circle.Y - Y
- _Y *= _Y
- If _X + _Y <= (Radius * Radius) + (Circle.Radius * Circle.Radius) Then Return True
- Return False
- End Function
- End Structure
- End Module
Advertisement
Add Comment
Please, Sign In to add comment