1 | #Region "Microsoft.VisualBasic::e6e08858ebd53e1cf616447fd793dbce, Microsoft.VisualBasic.Core\Extensions\Image\GDI+\Layouts\Rectangle2D.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 Rectangle2D |
35 | ' |
36 | ' Properties: CenterX, CenterY, Height, Rectangle, Width |
37 | ' |
38 | ' Constructor: (+6 Overloads) Sub New |
39 | ' |
40 | ' Function: Clone, contains, Equals, intersection, intersectLine |
41 | ' ToString |
42 | ' |
43 | ' Sub: add, grow, setRect |
44 | ' |
45 | ' |
46 | ' /********************************************************************************/ |
47 | |
48 | #End Region |
49 | |
50 | Imports System.Drawing |
51 | Imports System.Runtime.CompilerServices |
52 | Imports Microsoft.VisualBasic.Language |
53 | Imports sys = System.Math |
54 | |
55 | ' $Id: mxRectangle.java,v 1.1 2012/11/15 13:26:39 gaudenz Exp $ |
56 | ' Copyright (c) 2007-2010, Gaudenz Alder, David Benson |
57 | |
58 | Namespace Imaging.LayoutModel |
59 | |
60 | ''' <summary> |
61 | ''' Implements a 2-dimensional rectangle with double precision coordinates. |
62 | ''' </summary> |
63 | Public Class Rectangle2D : Inherits Point2D |
64 | |
65 | ''' <summary> |
66 | ''' Returns the width of the rectangle. |
67 | ''' </summary> |
68 | ''' <returns> Returns the width. </returns> |
69 | Public Overridable Property Width As Double |
70 | |
71 | ''' <summary> |
72 | ''' Returns the height of the rectangle. |
73 | ''' </summary> |
74 | ''' <returns> Returns the height. </returns> |
75 | Public Overridable Property Height As Double |
76 | |
77 | ''' <summary> |
78 | ''' Returns the x-coordinate of the center. |
79 | ''' </summary> |
80 | ''' <returns> Returns the x-coordinate of the center. </returns> |
81 | Public Overridable ReadOnly Property CenterX As Double |
82 | Get |
83 | Return X + Width / 2 |
84 | End Get |
85 | End Property |
86 | |
87 | ''' <summary> |
88 | ''' Returns the y-coordinate of the center. |
89 | ''' </summary> |
90 | ''' <returns> Returns the y-coordinate of the center. </returns> |
91 | Public Overridable ReadOnly Property CenterY As Double |
92 | Get |
93 | Return Y + Height / 2 |
94 | End Get |
95 | End Property |
96 | |
97 | ''' <summary> |
98 | ''' Constructs a new rectangle at (0, 0) with the width and height set to 0. |
99 | ''' </summary> |
100 | Public Sub New() |
101 | Me.New(0, 0, 0, 0) |
102 | End Sub |
103 | |
104 | ''' <summary> |
105 | ''' Constructs a copy of the given rectangle. |
106 | ''' </summary> |
107 | ''' <param name="rect"> Rectangle to construct a copy of. </param> |
108 | Public Sub New(rect As Rectangle) |
109 | Me.New(rect.X, rect.Y, rect.Width, rect.Height) |
110 | End Sub |
111 | |
112 | ''' <summary> |
113 | ''' Constructs a copy of the given rectangle. |
114 | ''' </summary> |
115 | ''' <param name="rect"> Rectangle to construct a copy of. </param> |
116 | Public Sub New(rect As RectangleF) |
117 | Me.New(rect.X, rect.Y, rect.Width, rect.Height) |
118 | End Sub |
119 | |
120 | ''' <summary> |
121 | ''' Constructs a copy of the given rectangle. |
122 | ''' </summary> |
123 | ''' <param name="rect"> Rectangle to construct a copy of. </param> |
124 | Public Sub New(rect As Rectangle2D) |
125 | Me.New(rect.X, rect.Y, rect.Width, rect.Height) |
126 | End Sub |
127 | |
128 | ''' <summary> |
129 | ''' Constructs a rectangle using the given parameters. |
130 | ''' </summary> |
131 | ''' <param name="x"> X-coordinate of the new rectangle. </param> |
132 | ''' <param name="y"> Y-coordinate of the new rectangle. </param> |
133 | ''' <param name="width"> Width of the new rectangle. </param> |
134 | ''' <param name="height"> Height of the new rectangle. </param> |
135 | Public Sub New(x As Double, y As Double, width As Double, height As Double) |
136 | MyBase.New(x, y) |
137 | |
138 | Me.Width = width |
139 | Me.Height = height |
140 | End Sub |
141 | |
142 | Sub New(width%, height%) |
143 | Call Me.New(0, 0, width, height) |
144 | End Sub |
145 | |
146 | ''' <summary> |
147 | ''' Sets this rectangle to the specified values |
148 | ''' </summary> |
149 | ''' <param name="x"> the new x-axis position </param> |
150 | ''' <param name="y"> the new y-axis position </param> |
151 | ''' <param name="w"> the new width of the rectangle </param> |
152 | ''' <param name="h"> the new height of the rectangle </param> |
153 | Public Overridable Sub setRect(x As Double, y As Double, w As Double, h As Double) |
154 | Me.X = x |
155 | Me.Y = y |
156 | Me.Width = w |
157 | Me.Height = h |
158 | End Sub |
159 | |
160 | ''' <summary> |
161 | ''' Adds the given rectangle to this rectangle. |
162 | ''' </summary> |
163 | Public Overridable Sub add(rect As Rectangle2D) |
164 | If rect IsNot Nothing Then |
165 | Dim minX As Double = sys.Min(X, rect.X) |
166 | Dim minY As Double = sys.Min(Y, rect.Y) |
167 | Dim maxX As Double = sys.Max(X + Width, rect.X + rect.Width) |
168 | Dim maxY As Double = sys.Max(Y + Height, rect.Y + rect.Height) |
169 | |
170 | X = minX |
171 | Y = minY |
172 | Width = maxX - minX |
173 | Height = maxY - minY |
174 | End If |
175 | End Sub |
176 | |
177 | ''' <summary> |
178 | ''' Grows the rectangle by the given amount, that is, this method subtracts |
179 | ''' the given amount from the x- and y-coordinates and adds twice the amount |
180 | ''' to the width and height. |
181 | ''' </summary> |
182 | ''' <param name="amount"> Amount by which the rectangle should be grown. </param> |
183 | Public Overridable Sub grow(amount As Double) |
184 | X -= amount |
185 | Y -= amount |
186 | Width += 2 * amount |
187 | Height += 2 * amount |
188 | End Sub |
189 | |
190 | ''' <summary> |
191 | ''' Returns true if the given point is contained in the rectangle. |
192 | ''' </summary> |
193 | ''' <param name="x"> X-coordinate of the point. </param> |
194 | ''' <param name="y"> Y-coordinate of the point. </param> |
195 | ''' <returns> Returns true if the point is contained in the rectangle.</returns> |
196 | ''' |
197 | <MethodImpl(MethodImplOptions.AggressiveInlining)> |
198 | Public Overridable Function contains(x As Double, y As Double) As Boolean |
199 | Return (Me.X <= x AndAlso Me.X + Width >= x AndAlso Me.Y <= y AndAlso Me.Y + Height >= y) |
200 | End Function |
201 | |
202 | ''' <summary> |
203 | ''' Returns the point at which the specified point intersects the perimeter |
204 | ''' of this rectangle or null if there is no intersection. |
205 | ''' </summary> |
206 | ''' <param name="x0"> the x co-ordinate of the first point of the line </param> |
207 | ''' <param name="y0"> the y co-ordinate of the first point of the line </param> |
208 | ''' <param name="x1"> the x co-ordinate of the second point of the line </param> |
209 | ''' <param name="y1"> the y co-ordinate of the second point of the line </param> |
210 | ''' <returns> |
211 | ''' The point at which the line intersects this rectangle, or null if there is no intersection |
212 | ''' </returns> |
213 | Public Overridable Function intersectLine(x0 As Double, y0 As Double, x1 As Double, y1 As Double) As Point2D |
214 | Dim result As Point2D = intersection(X, Y, X + Width, Y, x0, y0, x1, y1) |
215 | |
216 | If result Is Nothing Then result = intersection(X + Width, Y, X + Width, Y + Height, x0, y0, x1, y1) |
217 | If result Is Nothing Then result = intersection(X + Width, Y + Height, X, Y + Height, x0, y0, x1, y1) |
218 | If result Is Nothing Then result = intersection(X, Y, X, Y + Height, x0, y0, x1, y1) |
219 | |
220 | Return result |
221 | End Function |
222 | |
223 | ''' <summary> |
224 | ''' Returns the intersection of two lines as an mxPoint. |
225 | ''' </summary> |
226 | ''' <param name="x0">X-coordinate of the first line's startpoint.</param> |
227 | ''' <param name="y0">Y-coordinate of the first line's startpoint.</param> |
228 | ''' <param name="x1">X-coordinate of the first line's endpoint.</param> |
229 | ''' <param name="y1">Y-coordinate of the first line's endpoint.</param> |
230 | ''' <param name="x2">X-coordinate of the second line's startpoint.</param> |
231 | ''' <param name="y2">Y-coordinate of the second line's startpoint.</param> |
232 | ''' <param name="x3">X-coordinate of the second line's endpoint.</param> |
233 | ''' <param name="y3">Y-coordinate of the second line's endpoint.</param> |
234 | ''' <returns> Returns the intersection between the two lines.</returns> |
235 | Public Shared Function intersection(x0 As Double, y0 As Double, x1 As Double, y1 As Double, x2 As Double, y2 As Double, x3 As Double, y3 As Double) As Point2D |
236 | Dim denom As Double = ((y3 - y2) * (x1 - x0)) - ((x3 - x2) * (y1 - y0)) |
237 | Dim nume_a As Double = ((x3 - x2) * (y0 - y2)) - ((y3 - y2) * (x0 - x2)) |
238 | Dim nume_b As Double = ((x1 - x0) * (y0 - y2)) - ((y1 - y0) * (x0 - x2)) |
239 | Dim ua As Double = nume_a / denom |
240 | Dim ub As Double = nume_b / denom |
241 | |
242 | If ua >= 0.0 AndAlso ua <= 1.0 AndAlso ub >= 0.0 AndAlso ub <= 1.0 Then |
243 | ' Get the intersection point |
244 | Dim iX As Double = x0 + ua * (x1 - x0) |
245 | Dim iY As Double = y0 + ua * (y1 - y0) |
246 | |
247 | Return New Point2D(iX, iY) |
248 | Else |
249 | ' No intersection |
250 | Return Nothing |
251 | End If |
252 | End Function |
253 | |
254 | ''' <summary> |
255 | ''' Returns the bounds as a new rectangle. |
256 | ''' </summary> |
257 | ''' <returns> Returns a new rectangle for the bounds. </returns> |
258 | Public Overridable ReadOnly Property Rectangle As RectangleF |
259 | Get |
260 | Dim ix As Integer = CInt(Fix(sys.Round(X))) |
261 | Dim iy As Integer = CInt(Fix(sys.Round(Y))) |
262 | Dim iw As Integer = CInt(Fix(sys.Round(Width - ix + X))) |
263 | Dim ih As Integer = CInt(Fix(sys.Round(Height - iy + Y))) |
264 | |
265 | Return New RectangleF(ix, iy, iw, ih) |
266 | End Get |
267 | End Property |
268 | |
269 | ''' <summary> |
270 | ''' Returns true if the given object value equals this rectangle. |
271 | ''' </summary> |
272 | Public Overrides Function Equals(obj As Object) As Boolean |
273 | If TypeOf obj Is Rectangle2D Then |
274 | With TryCast(obj, Rectangle2D) |
275 | Return .X = X AndAlso |
276 | .Y = Y AndAlso |
277 | .Width = Width AndAlso |
278 | .Height = Height |
279 | End With |
280 | End If |
281 | |
282 | Return False |
283 | End Function |
284 | |
285 | ''' <summary> |
286 | ''' Returns a new instance of the same rectangle. |
287 | ''' </summary> |
288 | Public Overrides Function Clone() As Object |
289 | With CType(MyBase.Clone(), Rectangle2D) |
290 | .Width = Width |
291 | .Height = Height |
292 | |
293 | Return .ByRef |
294 | End With |
295 | End Function |
296 | |
297 | ''' <summary> |
298 | ''' Returns the <code>String</code> representation of this |
299 | ''' <code>mxRectangle</code>. </summary> |
300 | ''' <returns> a <code>String</code> representing this |
301 | ''' <code>mxRectangle</code>. </returns> |
302 | Public Overrides Function ToString() As String |
303 | Return $"{Me.GetType.Name} [x={X}, y={Y}, w={Width}, h={Height}]" |
304 | End Function |
305 | End Class |
306 | End Namespace |