1 #Region "Microsoft.VisualBasic::3de1704040fc26424f9297c075be7162, Microsoft.VisualBasic.Core\Extensions\Image\Math\Polygon2D.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 Polygon2D
35     
36     '         Constructor: (+2 OverloadsSub New
37     
38     '         Function: boundingInside, (+2 Overloads) inside
39     
40     '         Sub: calculateBounds
41     
42     
43     ' /********************************************************************************/
44
45 #End Region
46
47 Imports sys = System.Math
48
49 Namespace Imaging.Math2D
50
51     Public Class Polygon2D
52
53         Public npoints As Integer = 0
54         Public xpoints As Double() = New Double(3) {}
55         Public ypoints As Double() = New Double(3) {}
56
57         Protected Friend bounds1 As Vector2D = Nothing
58         Protected Friend bounds2 As Vector2D = Nothing
59
60         Public Sub New()
61         End Sub
62
63         Public Sub New(x As Double(), y As Double(), points As Integer)
64             Me.npoints = points
65             Me.xpoints = New Double(points - 1) {}
66             Me.ypoints = New Double(points - 1) {}
67
68             Array.Copy(x, 0, Me.xpoints, 0, points)
69             Array.Copy(y, 0, Me.ypoints, 0, points)
70
71             Call calculateBounds(x, y, points)
72         End Sub
73
74         Friend Overridable Sub calculateBounds(x As Double(), y As Double(), n As Integer)
75             Dim d1 As Double = Double.MaxValue
76             Dim d2 As Double = Double.MaxValue
77             Dim d3 As Double = Double.MinValue
78             Dim d4 As Double = Double.MinValue
79
80             For i As Integer = 0 To n - 1
81                 Dim d5 As Double = x(i)
82                 d1 = sys.Min(d1, d5)
83                 d3 = Math.Max(d3, d5)
84                 Dim d6 As Double = y(i)
85                 d2 = sys.Min(d2, d6)
86                 d4 = Math.Max(d4, d6)
87             Next
88
89             Me.bounds1 = New Vector2D(d1, d2)
90             Me.bounds2 = New Vector2D(d3, d4)
91         End Sub
92
93         Friend Overridable Function boundingInside(x As Double, y As DoubleAs Boolean
94             Return (x >= Me.bounds1.x) AndAlso (x <= Me.bounds2.x) AndAlso (y >= Me.bounds1.y) AndAlso (y <= Me.bounds2.y)
95         End Function
96
97         Public Overridable Function inside(paramVector2D As Vector2D) As Boolean
98             Return inside(paramVector2D.x, paramVector2D.y)
99         End Function
100
101         ''' <summary>
102         ''' @deprecated
103         ''' </summary>
104         Public Overridable Function inside(x As Double, y As DoubleAs Boolean
105             If boundingInside(x, y) Then
106                 Dim i As Integer = 0
107                 Dim d1 As Double = 0.0
108                 Dim j As Integer = 0
109                 While (j < Me.npoints) AndAlso (Me.ypoints(j) = y)
110                     j += 1
111                 End While
112                 For k As Integer = 0 To Me.npoints - 1
113                     Dim m As Integer = (j + 1) Mod Me.npoints
114                     Dim d2 As Double = Me.xpoints(m) - Me.xpoints(j)
115                     Dim d3 As Double = Me.ypoints(m) - Me.ypoints(j)
116                     If d3 <> 0.0 Then
117                         Dim d4 As Double = x - Me.xpoints(j)
118                         Dim d5 As Double = y - Me.ypoints(j)
119                         If (Me.ypoints(m) = y) AndAlso (Me.xpoints(m) >= x) Then
120                             d1 = Me.ypoints(j)
121                         End If
122                         If (Me.ypoints(j) = y) AndAlso (Me.xpoints(j) >= x) Then
123                             If (If(d1 > y, 1, 0)) <> (If(Me.ypoints(m) > y, 1, 0)) Then
124                                 i -= 1
125                             End If
126                         End If
127                         Dim f As Single = CSng(d5) / CSng(d3)
128                         If (f >= 0.0) AndAlso (f <= 1.0) AndAlso (f * d2 >= d4) Then
129                             i += 1
130                         End If
131                     End If
132                     j = m
133                 Next
134                 Return i Mod 2 <> 0
135             End If
136             Return False
137         End Function
138     End Class
139 End Namespace