2020-05-21 22:27:25 +08:00
|
|
|
|
#Region "Microsoft.VisualBasic::566a4adfde30cf1a6f4dc770db618305, Microsoft.VisualBasic.Core\Extensions\Image\Math\VectorMath2D.vb"
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
|
|
|
|
|
' Author:
|
|
|
|
|
|
'
|
|
|
|
|
|
' asuka (amethyst.asuka@gcmodeller.org)
|
|
|
|
|
|
' xie (genetics@smrucc.org)
|
|
|
|
|
|
' xieguigang (xie.guigang@live.com)
|
|
|
|
|
|
'
|
|
|
|
|
|
' Copyright (c) 2018 GPL3 Licensed
|
|
|
|
|
|
'
|
|
|
|
|
|
'
|
|
|
|
|
|
' GNU GENERAL PUBLIC LICENSE (GPL3)
|
|
|
|
|
|
'
|
|
|
|
|
|
'
|
|
|
|
|
|
' This program is free software: you can redistribute it and/or modify
|
|
|
|
|
|
' it under the terms of the GNU General Public License as published by
|
|
|
|
|
|
' the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
|
' (at your option) any later version.
|
|
|
|
|
|
'
|
|
|
|
|
|
' This program is distributed in the hope that it will be useful,
|
|
|
|
|
|
' but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
|
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
|
' GNU General Public License for more details.
|
|
|
|
|
|
'
|
|
|
|
|
|
' You should have received a copy of the GNU General Public License
|
|
|
|
|
|
' along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
' /********************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
' Summaries:
|
|
|
|
|
|
|
|
|
|
|
|
' Class VectorMath2D
|
|
|
|
|
|
'
|
|
|
|
|
|
' Function: absAngle, absAngleDeg, add, angle, angleDeg
|
|
|
|
|
|
' (+3 Overloads) createPointAuto, innerProduct, isNear, length, subtract
|
|
|
|
|
|
'
|
|
|
|
|
|
'
|
|
|
|
|
|
' /********************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
#End Region
|
|
|
|
|
|
|
|
|
|
|
|
Imports Microsoft.VisualBasic.Imaging.LayoutModel
|
2020-03-03 19:38:49 +08:00
|
|
|
|
Imports stdNum = System.Math
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
|
|
|
|
|
Namespace Imaging.Math2D
|
|
|
|
|
|
|
|
|
|
|
|
Public Class VectorMath2D
|
|
|
|
|
|
|
|
|
|
|
|
Public Shared Function add(paramVector2D1 As Vector2D, paramVector2D2 As Vector2D) As Vector2D
|
|
|
|
|
|
Return New Vector2D(paramVector2D1.x + paramVector2D2.x, paramVector2D1.y + paramVector2D2.y)
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
Public Shared Function subtract(paramVector2D1 As Vector2D, paramVector2D2 As Vector2D) As Vector2D
|
|
|
|
|
|
Return New Vector2D(paramVector2D1.x - paramVector2D2.x, paramVector2D1.y - paramVector2D2.y)
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
Public Shared Function length(paramVector2D As Vector2D) As Double
|
2020-04-17 18:31:10 +08:00
|
|
|
|
Return stdNum.Sqrt(paramVector2D.x * paramVector2D.x + paramVector2D.y * paramVector2D.y)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
Public Shared Function absAngle(paramVector2D1 As Vector2D, paramVector2D2 As Vector2D) As Double
|
|
|
|
|
|
Dim d1 As Double = paramVector2D1.Length()
|
|
|
|
|
|
Dim d2 As Double = paramVector2D2.Length()
|
|
|
|
|
|
If d1 = 0.0 Then
|
|
|
|
|
|
Return 0.0
|
|
|
|
|
|
End If
|
|
|
|
|
|
If d2 = 0.0 Then
|
|
|
|
|
|
Return 0.0
|
|
|
|
|
|
End If
|
|
|
|
|
|
Dim d3 As Double = innerProduct(paramVector2D1, paramVector2D2) / d1 / d2
|
|
|
|
|
|
If d3 >= 1.0 Then
|
|
|
|
|
|
d3 = 1.0
|
|
|
|
|
|
End If
|
|
|
|
|
|
If d3 <= -1.0 Then
|
|
|
|
|
|
d3 = -1.0
|
|
|
|
|
|
End If
|
2020-04-17 18:31:10 +08:00
|
|
|
|
Return stdNum.Acos(d3)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
Public Shared Function absAngleDeg(paramVector2D1 As Vector2D, paramVector2D2 As Vector2D) As Double
|
|
|
|
|
|
Return absAngle(paramVector2D1, paramVector2D2) * 180.0 / 3.14159265358979
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
Public Shared Function angle(paramVector2D1 As Vector2D, paramVector2D2 As Vector2D) As Double
|
|
|
|
|
|
Dim d2 As Double = absAngle(paramVector2D1, paramVector2D2)
|
|
|
|
|
|
If paramVector2D1.y = 0.0 Then
|
|
|
|
|
|
If paramVector2D1.x > 0.0 Then
|
|
|
|
|
|
If paramVector2D2.y < 0.0 Then
|
|
|
|
|
|
Return d2
|
|
|
|
|
|
End If
|
|
|
|
|
|
Return -d2
|
|
|
|
|
|
End If
|
|
|
|
|
|
If paramVector2D2.y < 0.0 Then
|
|
|
|
|
|
Return -d2
|
|
|
|
|
|
End If
|
|
|
|
|
|
Return d2
|
|
|
|
|
|
End If
|
|
|
|
|
|
Dim d1 As Double = paramVector2D2.y * paramVector2D1.x - paramVector2D2.x * paramVector2D1.y
|
|
|
|
|
|
If d1 < 0.0 Then
|
|
|
|
|
|
Return d2
|
|
|
|
|
|
End If
|
|
|
|
|
|
Return -d2
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
Public Shared Function angleDeg(paramVector2D1 As Vector2D, paramVector2D2 As Vector2D) As Double
|
2020-03-03 19:38:49 +08:00
|
|
|
|
Return angle(paramVector2D1, paramVector2D2) * 180.0 / stdNum.PI
|
2018-08-02 20:14:48 +08:00
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
Public Shared Function innerProduct(paramVector2D1 As Vector2D, paramVector2D2 As Vector2D) As Double
|
|
|
|
|
|
Return paramVector2D1.x * paramVector2D2.x + paramVector2D1.y * paramVector2D2.y
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
Public Shared Function isNear(paramDouble1 As Double, paramDouble2 As Double, paramDouble3 As Double, paramDouble4 As Double, paramDouble5 As Double, paramDouble6 As Double,
|
|
|
|
|
|
paramDouble7 As Double) As Boolean
|
2020-03-03 19:38:49 +08:00
|
|
|
|
If stdNum.Min(paramDouble1, paramDouble3) > paramDouble5 + paramDouble7 Then
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Return False
|
|
|
|
|
|
End If
|
2020-04-17 18:31:10 +08:00
|
|
|
|
If stdNum.Max(paramDouble1, paramDouble3) < paramDouble5 - paramDouble7 Then
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Return False
|
|
|
|
|
|
End If
|
2020-03-03 19:38:49 +08:00
|
|
|
|
If stdNum.Min(paramDouble2, paramDouble4) > paramDouble6 + paramDouble7 Then
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Return False
|
|
|
|
|
|
End If
|
2020-04-17 18:31:10 +08:00
|
|
|
|
If stdNum.Max(paramDouble2, paramDouble4) < paramDouble6 - paramDouble7 Then
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Return False
|
|
|
|
|
|
End If
|
|
|
|
|
|
Dim d1 As Double = paramDouble4 - paramDouble2
|
|
|
|
|
|
Dim d2 As Double = paramDouble1 - paramDouble3
|
|
|
|
|
|
Dim d3 As Double = paramDouble3 * paramDouble2 - paramDouble1 * paramDouble4
|
|
|
|
|
|
Dim d4 As Double = (d1 * paramDouble5 + d2 * paramDouble6 + d3) * (d1 * paramDouble5 + d2 * paramDouble6 + d3) / (d1 * d1 + d2 * d2)
|
|
|
|
|
|
Return d4 < paramDouble7 * paramDouble7
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
2018-11-26 19:18:01 +08:00
|
|
|
|
Public Shared Function createPointAuto(dimension1 As Rectangle2D, dimension2 As Rectangle2D, paramInt As Integer) As Rectangle2D
|
|
|
|
|
|
Dim localDimension As New Rectangle2D()
|
|
|
|
|
|
Dim i As Integer = dimension2.Width - dimension1.Width
|
|
|
|
|
|
Dim j As Integer = dimension2.Height - dimension1.Height
|
2020-04-17 18:31:10 +08:00
|
|
|
|
Dim d3 As Double = stdNum.Sqrt(i * i + j * j)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Dim d1 As Double = 0.8660254 * i - 0.5 * j
|
|
|
|
|
|
Dim d2 As Double = -0.8660254 * i - 0.5 * j
|
2018-11-26 19:18:01 +08:00
|
|
|
|
|
2020-04-17 18:31:10 +08:00
|
|
|
|
If stdNum.Abs(d1) < stdNum.Abs(d2) Then
|
|
|
|
|
|
dimension1.Width += CInt(stdNum.Truncate((-0.5 * i - 0.8660254 * j) * paramInt / d3))
|
|
|
|
|
|
dimension1.Height += CInt(stdNum.Truncate(d1 * paramInt / d3))
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Else
|
2020-04-17 18:31:10 +08:00
|
|
|
|
dimension1.Width += CInt(stdNum.Truncate((-0.5 * i + 0.8660254 * j) * paramInt / d3))
|
|
|
|
|
|
dimension1.Height += CInt(stdNum.Truncate(d2 * paramInt / d3))
|
2018-08-02 20:14:48 +08:00
|
|
|
|
End If
|
2018-11-26 19:18:01 +08:00
|
|
|
|
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Return localDimension
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
2018-11-26 19:18:01 +08:00
|
|
|
|
Public Shared Function createPointAuto(paramDimension1 As Rectangle2D, paramDimension2 As Rectangle2D, paramDimension3 As Rectangle2D, paramInt As Integer) As Rectangle2D
|
|
|
|
|
|
Dim localDimension As New Rectangle2D()
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Dim localVector2D2 As New Vector2D(paramDimension2.Width - paramDimension1.Width, paramDimension2.Height - paramDimension1.Height)
|
|
|
|
|
|
Dim localVector2D3 As New Vector2D(paramDimension3.Width - paramDimension1.Width, paramDimension3.Height - paramDimension1.Height)
|
|
|
|
|
|
localVector2D2 = localVector2D2 * (1.0 / localVector2D2.Length())
|
|
|
|
|
|
localVector2D3 = localVector2D3 * (1.0 / localVector2D3.Length())
|
|
|
|
|
|
Dim localVector2D1 As Vector2D = add(localVector2D2, localVector2D3)
|
|
|
|
|
|
localVector2D1 = localVector2D1 * (paramInt / localVector2D1.Length())
|
2020-04-17 18:31:10 +08:00
|
|
|
|
paramDimension1.Width -= CInt(stdNum.Truncate(localVector2D1.x))
|
|
|
|
|
|
paramDimension1.Height -= CInt(stdNum.Truncate(localVector2D1.y))
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Return localDimension
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
2018-11-26 19:18:01 +08:00
|
|
|
|
Public Shared Function createPointAuto(paramDimension As Rectangle2D, paramVector As ArrayList, paramInt As Integer) As Rectangle2D
|
|
|
|
|
|
Dim localDimension As New Rectangle2D()
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Dim d1 As Double = 360.0
|
|
|
|
|
|
Dim d2 As Double = 360.0
|
|
|
|
|
|
Dim d3 As Double = 0.0
|
|
|
|
|
|
Dim i As Integer = paramVector.Count
|
|
|
|
|
|
Dim j As Integer = 0
|
|
|
|
|
|
Dim k As Integer = 1
|
|
|
|
|
|
Dim m As Integer = -1
|
|
|
|
|
|
Dim n As Integer = -1
|
|
|
|
|
|
Dim i1 As Integer = -1
|
|
|
|
|
|
Dim arrayOfBoolean As Boolean() = New Boolean(paramVector.Count - 1) {}
|
|
|
|
|
|
For i2 As Integer = 0 To paramVector.Count - 1
|
|
|
|
|
|
arrayOfBoolean(i2) = False
|
|
|
|
|
|
Next
|
|
|
|
|
|
|
|
|
|
|
|
Dim localVector2D2 As Vector2D
|
|
|
|
|
|
Dim localVector2D3 As Vector2D
|
|
|
|
|
|
|
|
|
|
|
|
While i > 0
|
2018-11-26 19:18:01 +08:00
|
|
|
|
localVector2D2 = New Vector2D(DirectCast(paramVector(j), Rectangle2D).Width - paramDimension.Width, DirectCast(paramVector(j), Rectangle2D).Height - paramDimension.Height)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
d2 = 360.0
|
|
|
|
|
|
m = -1
|
|
|
|
|
|
For k = 0 To paramVector.Count - 1
|
|
|
|
|
|
If (arrayOfBoolean(k) = 0) AndAlso (j <> k) Then
|
2018-11-26 19:18:01 +08:00
|
|
|
|
localVector2D3 = New Vector2D(DirectCast(paramVector(k), Rectangle2D).Width - paramDimension.Width, DirectCast(paramVector(k), Rectangle2D).Height - paramDimension.Height)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
d1 = angleDeg(localVector2D2, localVector2D3)
|
|
|
|
|
|
If d1 < 0.0 Then
|
|
|
|
|
|
d1 += 360.0
|
|
|
|
|
|
End If
|
|
|
|
|
|
If d1 < d2 Then
|
|
|
|
|
|
m = k
|
|
|
|
|
|
d2 = d1
|
|
|
|
|
|
End If
|
|
|
|
|
|
End If
|
|
|
|
|
|
Next
|
|
|
|
|
|
If d3 < d2 Then
|
|
|
|
|
|
n = j
|
|
|
|
|
|
i1 = m
|
|
|
|
|
|
d3 = d2
|
|
|
|
|
|
End If
|
|
|
|
|
|
j = m
|
|
|
|
|
|
arrayOfBoolean(m) = True
|
|
|
|
|
|
i -= 1
|
|
|
|
|
|
End While
|
2018-11-26 19:18:01 +08:00
|
|
|
|
localVector2D2 = New Vector2D(DirectCast(paramVector(n), Rectangle2D).Width - paramDimension.Width, DirectCast(paramVector(n), Rectangle2D).Height - paramDimension.Height)
|
|
|
|
|
|
localVector2D3 = New Vector2D(DirectCast(paramVector(i1), Rectangle2D).Width - paramDimension.Width, DirectCast(paramVector(i1), Rectangle2D).Height - paramDimension.Height)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
localVector2D2 = localVector2D2 * (1.0 / localVector2D2.Length())
|
|
|
|
|
|
localVector2D3 = localVector2D3 * (1.0 / localVector2D3.Length())
|
|
|
|
|
|
Dim localVector2D1 As Vector2D = add(localVector2D2, localVector2D3)
|
|
|
|
|
|
localVector2D1 = localVector2D1 * (paramInt / localVector2D1.Length())
|
2020-04-17 18:31:10 +08:00
|
|
|
|
paramDimension.Width += CInt(stdNum.Truncate(localVector2D1.x))
|
|
|
|
|
|
paramDimension.Height += CInt(stdNum.Truncate(localVector2D1.y))
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Return localDimension
|
|
|
|
|
|
End Function
|
|
|
|
|
|
End Class
|
|
|
|
|
|
End Namespace
|