1 #Region "Microsoft.VisualBasic::5d5f0bd2478a6e520928f570ff53c5b5, 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 / sys.PI
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(dimension1 As Rectangle2D, dimension2 As Rectangle2D, paramInt As IntegerAs Rectangle2D
137             Dim localDimension As New Rectangle2D()
138             Dim i As Integer = dimension2.Width - dimension1.Width
139             Dim j As Integer = dimension2.Height - dimension1.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
144             If Math.Abs(d1) < Math.Abs(d2) Then
145                 dimension1.Width += CInt(Math.Truncate((-0.5 * i - 0.8660254 * j) * paramInt / d3))
146                 dimension1.Height += CInt(Math.Truncate(d1 * paramInt / d3))
147             Else
148                 dimension1.Width += CInt(Math.Truncate((-0.5 * i + 0.8660254 * j) * paramInt / d3))
149                 dimension1.Height += CInt(Math.Truncate(d2 * paramInt / d3))
150             End If
151
152             Return localDimension
153         End Function
154
155         Public Shared Function createPointAuto(paramDimension1 As Rectangle2D, paramDimension2 As Rectangle2D, paramDimension3 As Rectangle2D, paramInt As IntegerAs Rectangle2D
156             Dim localDimension As New Rectangle2D()
157             Dim localVector2D2 As New Vector2D(paramDimension2.Width - paramDimension1.Width, paramDimension2.Height - paramDimension1.Height)
158             Dim localVector2D3 As New Vector2D(paramDimension3.Width - paramDimension1.Width, paramDimension3.Height - paramDimension1.Height)
159             localVector2D2 = localVector2D2 * (1.0 / localVector2D2.Length())
160             localVector2D3 = localVector2D3 * (1.0 / localVector2D3.Length())
161             Dim localVector2D1 As Vector2D = add(localVector2D2, localVector2D3)
162             localVector2D1 = localVector2D1 * (paramInt / localVector2D1.Length())
163             paramDimension1.Width -= CInt(Math.Truncate(localVector2D1.x))
164             paramDimension1.Height -= CInt(Math.Truncate(localVector2D1.y))
165             Return localDimension
166         End Function
167
168         Public Shared Function createPointAuto(paramDimension As Rectangle2D, paramVector As ArrayList, paramInt As IntegerAs Rectangle2D
169             Dim localDimension As New Rectangle2D()
170             Dim d1 As Double = 360.0
171             Dim d2 As Double = 360.0
172             Dim d3 As Double = 0.0
173             Dim i As Integer = paramVector.Count
174             Dim j As Integer = 0
175             Dim k As Integer = 1
176             Dim m As Integer = -1
177             Dim n As Integer = -1
178             Dim i1 As Integer = -1
179             Dim arrayOfBoolean As Boolean() = New Boolean(paramVector.Count - 1) {}
180             For i2 As Integer = 0 To paramVector.Count - 1
181                 arrayOfBoolean(i2) = False
182             Next
183
184             Dim localVector2D2 As Vector2D
185             Dim localVector2D3 As Vector2D
186
187             While i > 0
188                 localVector2D2 = New Vector2D(DirectCast(paramVector(j), Rectangle2D).Width - paramDimension.Width, DirectCast(paramVector(j), Rectangle2D).Height - paramDimension.Height)
189                 d2 = 360.0
190                 m = -1
191                 For k = 0 To paramVector.Count - 1
192                     If (arrayOfBoolean(k) = 0) AndAlso (j <> k) Then
193                         localVector2D3 = New Vector2D(DirectCast(paramVector(k), Rectangle2D).Width - paramDimension.Width, DirectCast(paramVector(k), Rectangle2D).Height - paramDimension.Height)
194                         d1 = angleDeg(localVector2D2, localVector2D3)
195                         If d1 < 0.0 Then
196                             d1 += 360.0
197                         End If
198                         If d1 < d2 Then
199                             m = k
200                             d2 = d1
201                         End If
202                     End If
203                 Next
204                 If d3 < d2 Then
205                     n = j
206                     i1 = m
207                     d3 = d2
208                 End If
209                 j = m
210                 arrayOfBoolean(m) = True
211                 i -= 1
212             End While
213             localVector2D2 = New Vector2D(DirectCast(paramVector(n), Rectangle2D).Width - paramDimension.Width, DirectCast(paramVector(n), Rectangle2D).Height - paramDimension.Height)
214             localVector2D3 = New Vector2D(DirectCast(paramVector(i1), Rectangle2D).Width - paramDimension.Width, DirectCast(paramVector(i1), Rectangle2D).Height - paramDimension.Height)
215             localVector2D2 = localVector2D2 * (1.0 / localVector2D2.Length())
216             localVector2D3 = localVector2D3 * (1.0 / localVector2D3.Length())
217             Dim localVector2D1 As Vector2D = add(localVector2D2, localVector2D3)
218             localVector2D1 = localVector2D1 * (paramInt / localVector2D1.Length())
219             paramDimension.Width += CInt(Math.Truncate(localVector2D1.x))
220             paramDimension.Height += CInt(Math.Truncate(localVector2D1.y))
221             Return localDimension
222         End Function
223     End Class
224 End Namespace