1 #Region "Microsoft.VisualBasic::d5b1ce7d4e0a365aa6eb8e8f7ba1b7de, Microsoft.VisualBasic.Core\Extensions\Image\Math\VectorMath2D.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Class VectorMath2D
35     
36     '         Function: absAngle, absAngleDeg, add, angle, angleDeg
37     '                   (+3 Overloads) createPointAuto, innerProduct, isNear, length, subtract
38     
39     
40     ' /********************************************************************************/
41
42 #End Region
43
44 Imports Microsoft.VisualBasic.Imaging.LayoutModel
45 Imports sys = System.Math
46
47 Namespace Imaging.Math2D
48
49     Public Class VectorMath2D
50
51         Public Shared Function add(paramVector2D1 As Vector2D, paramVector2D2 As Vector2D) As Vector2D
52             Return New Vector2D(paramVector2D1.x + paramVector2D2.x, paramVector2D1.y + paramVector2D2.y)
53         End Function
54
55         Public Shared Function subtract(paramVector2D1 As Vector2D, paramVector2D2 As Vector2D) As Vector2D
56             Return New Vector2D(paramVector2D1.x - paramVector2D2.x, paramVector2D1.y - paramVector2D2.y)
57         End Function
58
59         Public Shared Function length(paramVector2D As Vector2D) As Double
60             Return Math.Sqrt(paramVector2D.x * paramVector2D.x + paramVector2D.y * paramVector2D.y)
61         End Function
62
63         Public Shared Function absAngle(paramVector2D1 As Vector2D, paramVector2D2 As Vector2D) As Double
64             Dim d1 As Double = paramVector2D1.Length()
65             Dim d2 As Double = paramVector2D2.Length()
66             If d1 = 0.0 Then
67                 Return 0.0
68             End If
69             If d2 = 0.0 Then
70                 Return 0.0
71             End If
72             Dim d3 As Double = innerProduct(paramVector2D1, paramVector2D2) / d1 / d2
73             If d3 >= 1.0 Then
74                 d3 = 1.0
75             End If
76             If d3 <= -1.0 Then
77                 d3 = -1.0
78             End If
79             Return Math.Acos(d3)
80         End Function
81
82         Public Shared Function absAngleDeg(paramVector2D1 As Vector2D, paramVector2D2 As Vector2D) As Double
83             Return absAngle(paramVector2D1, paramVector2D2) * 180.0 / 3.14159265358979
84         End Function
85
86         Public Shared Function angle(paramVector2D1 As Vector2D, paramVector2D2 As Vector2D) As Double
87             Dim d2 As Double = absAngle(paramVector2D1, paramVector2D2)
88             If paramVector2D1.y = 0.0 Then
89                 If paramVector2D1.x > 0.0 Then
90                     If paramVector2D2.y < 0.0 Then
91                         Return d2
92                     End If
93                     Return -d2
94                 End If
95                 If paramVector2D2.y < 0.0 Then
96                     Return -d2
97                 End If
98                 Return d2
99             End If
100             Dim d1 As Double = paramVector2D2.y * paramVector2D1.x - paramVector2D2.x * paramVector2D1.y
101             If d1 < 0.0 Then
102                 Return d2
103             End If
104             Return -d2
105         End Function
106
107         Public Shared Function angleDeg(paramVector2D1 As Vector2D, paramVector2D2 As Vector2D) As Double
108             Return angle(paramVector2D1, paramVector2D2) * 180.0 / 3.14159265358979
109         End Function
110
111         Public Shared Function innerProduct(paramVector2D1 As Vector2D, paramVector2D2 As Vector2D) As Double
112             Return paramVector2D1.x * paramVector2D2.x + paramVector2D1.y * paramVector2D2.y
113         End Function
114
115         Public Shared Function isNear(paramDouble1 As Double, paramDouble2 As Double, paramDouble3 As Double, paramDouble4 As Double, paramDouble5 As Double, paramDouble6 As Double,
116             paramDouble7 As DoubleAs Boolean
117             If sys.Min(paramDouble1, paramDouble3) > paramDouble5 + paramDouble7 Then
118                 Return False
119             End If
120             If Math.Max(paramDouble1, paramDouble3) < paramDouble5 - paramDouble7 Then
121                 Return False
122             End If
123             If sys.Min(paramDouble2, paramDouble4) > paramDouble6 + paramDouble7 Then
124                 Return False
125             End If
126             If Math.Max(paramDouble2, paramDouble4) < paramDouble6 - paramDouble7 Then
127                 Return False
128             End If
129             Dim d1 As Double = paramDouble4 - paramDouble2
130             Dim d2 As Double = paramDouble1 - paramDouble3
131             Dim d3 As Double = paramDouble3 * paramDouble2 - paramDouble1 * paramDouble4
132             Dim d4 As Double = (d1 * paramDouble5 + d2 * paramDouble6 + d3) * (d1 * paramDouble5 + d2 * paramDouble6 + d3) / (d1 * d1 + d2 * d2)
133             Return d4 < paramDouble7 * paramDouble7
134         End Function
135
136         Public Shared Function createPointAuto(paramDimension1 As DblRect, paramDimension2 As DblRect, paramInt As IntegerAs DblRect
137             Dim localDimension As New DblRect()
138             Dim i As Integer = paramDimension2.Width - paramDimension1.Width
139             Dim j As Integer = paramDimension2.Height - paramDimension1.Height
140             Dim d3 As Double = Math.Sqrt(i * i + j * j)
141             Dim d1 As Double = 0.8660254 * i - 0.5 * j
142             Dim d2 As Double = -0.8660254 * i - 0.5 * j
143             If Math.Abs(d1) < Math.Abs(d2) Then
144                 paramDimension1.Width += CInt(Math.Truncate((-0.5 * i - 0.8660254 * j) * paramInt / d3))
145                 paramDimension1.Height += CInt(Math.Truncate(d1 * paramInt / d3))
146             Else
147                 paramDimension1.Width += CInt(Math.Truncate((-0.5 * i + 0.8660254 * j) * paramInt / d3))
148                 paramDimension1.Height += CInt(Math.Truncate(d2 * paramInt / d3))
149             End If
150             Return localDimension
151         End Function
152
153         Public Shared Function createPointAuto(paramDimension1 As DblRect, paramDimension2 As DblRect, paramDimension3 As DblRect, paramInt As IntegerAs DblRect
154             Dim localDimension As New DblRect()
155             Dim localVector2D2 As New Vector2D(paramDimension2.Width - paramDimension1.Width, paramDimension2.Height - paramDimension1.Height)
156             Dim localVector2D3 As New Vector2D(paramDimension3.Width - paramDimension1.Width, paramDimension3.Height - paramDimension1.Height)
157             localVector2D2 = localVector2D2 * (1.0 / localVector2D2.Length())
158             localVector2D3 = localVector2D3 * (1.0 / localVector2D3.Length())
159             Dim localVector2D1 As Vector2D = add(localVector2D2, localVector2D3)
160             localVector2D1 = localVector2D1 * (paramInt / localVector2D1.Length())
161             paramDimension1.Width -= CInt(Math.Truncate(localVector2D1.x))
162             paramDimension1.Height -= CInt(Math.Truncate(localVector2D1.y))
163             Return localDimension
164         End Function
165
166         Public Shared Function createPointAuto(paramDimension As DblRect, paramVector As ArrayList, paramInt As IntegerAs DblRect
167             Dim localDimension As New DblRect()
168             Dim d1 As Double = 360.0
169             Dim d2 As Double = 360.0
170             Dim d3 As Double = 0.0
171             Dim i As Integer = paramVector.Count
172             Dim j As Integer = 0
173             Dim k As Integer = 1
174             Dim m As Integer = -1
175             Dim n As Integer = -1
176             Dim i1 As Integer = -1
177             Dim arrayOfBoolean As Boolean() = New Boolean(paramVector.Count - 1) {}
178             For i2 As Integer = 0 To paramVector.Count - 1
179                 arrayOfBoolean(i2) = False
180             Next
181
182             Dim localVector2D2 As Vector2D
183             Dim localVector2D3 As Vector2D
184
185             While i > 0
186                 localVector2D2 = New Vector2D(DirectCast(paramVector(j), DblRect).Width - paramDimension.Width, DirectCast(paramVector(j), DblRect).Height - paramDimension.Height)
187                 d2 = 360.0
188                 m = -1
189                 For k = 0 To paramVector.Count - 1
190                     If (arrayOfBoolean(k) = 0) AndAlso (j <> k) Then
191                         localVector2D3 = New Vector2D(DirectCast(paramVector(k), DblRect).Width - paramDimension.Width, DirectCast(paramVector(k), DblRect).Height - paramDimension.Height)
192                         d1 = angleDeg(localVector2D2, localVector2D3)
193                         If d1 < 0.0 Then
194                             d1 += 360.0
195                         End If
196                         If d1 < d2 Then
197                             m = k
198                             d2 = d1
199                         End If
200                     End If
201                 Next
202                 If d3 < d2 Then
203                     n = j
204                     i1 = m
205                     d3 = d2
206                 End If
207                 j = m
208                 arrayOfBoolean(m) = True
209                 i -= 1
210             End While
211             localVector2D2 = New Vector2D(DirectCast(paramVector(n), DblRect).Width - paramDimension.Width, DirectCast(paramVector(n), DblRect).Height - paramDimension.Height)
212             localVector2D3 = New Vector2D(DirectCast(paramVector(i1), DblRect).Width - paramDimension.Width, DirectCast(paramVector(i1), DblRect).Height - paramDimension.Height)
213             localVector2D2 = localVector2D2 * (1.0 / localVector2D2.Length())
214             localVector2D3 = localVector2D3 * (1.0 / localVector2D3.Length())
215             Dim localVector2D1 As Vector2D = add(localVector2D2, localVector2D3)
216             localVector2D1 = localVector2D1 * (paramInt / localVector2D1.Length())
217             paramDimension.Width += CInt(Math.Truncate(localVector2D1.x))
218             paramDimension.Height += CInt(Math.Truncate(localVector2D1.y))
219             Return localDimension
220         End Function
221     End Class
222 End Namespace