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 OverloadsSub 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 DoubleAs 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 DoubleAs 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 DoubleAs 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 ObjectAs 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