MuPDFCore 1.8.0
Multiplatform .NET bindings for MuPDF
Loading...
Searching...
No Matches
Rectangles.cs
1/*
2 MuPDFCore - A set of multiplatform .NET Core bindings for MuPDF.
3 Copyright (C) 2020 Giorgio Bianchini
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Affero General Public License as
7 published by the Free Software Foundation, version 3.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Affero General Public License for more details.
13
14 You should have received a copy of the GNU Affero General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>
16*/
17
18using System;
19
20namespace MuPDFCore
21{
22 /// <summary>
23 /// Represents the size of a rectangle.
24 /// </summary>
25 public struct Size
26 {
27 /// <summary>
28 /// The width of the rectangle.
29 /// </summary>
30 public float Width;
31
32 /// <summary>
33 /// The height of the rectangle.
34 /// </summary>
35 public float Height;
36
37 /// <summary>
38 /// Create a new <see cref="Size"/> with the specified width and height.
39 /// </summary>
40 /// <param name="width">The width of the rectangle.</param>
41 /// <param name="height">The height of the rectangle.</param>
42 public Size(float width, float height)
43 {
44 Width = width;
45 Height = height;
46 }
47
48 /// <summary>
49 /// Create a new <see cref="Size"/> with the specified width and height.
50 /// </summary>
51 /// <param name="width">The width of the rectangle.</param>
52 /// <param name="height">The height of the rectangle.</param>
53 public Size(double width, double height)
54 {
55 Width = (float)width;
56 Height = (float)height;
57 }
58
59 /// <summary>
60 /// Split the size into the specified number of <see cref="Rectangle"/>s.
61 /// </summary>
62 /// <param name="divisions">The number of rectangles in which the size should be split. This must be factorisable using only powers of 2, 3, 5 or 7. Otherwise, the biggest number smaller than <paramref name="divisions"/> that satisfies this condition is used.</param>
63 /// <returns>An array of <see cref="Rectangle"/>s that when positioned properly cover an area of the size of this object.</returns>
64 public Rectangle[] Split(int divisions)
65 {
66 divisions = Utils.GetAcceptableNumber(divisions);
67
68 Rectangle[] tbr = new Rectangle[divisions];
69
70 bool isVertical = this.Height > this.Width;
71
72 if (divisions == 1)
73 {
74 tbr[0] = new Rectangle(0, 0, Width, Height);
75 }
76 else if (divisions == 2)
77 {
78 if (isVertical)
79 {
80 tbr[0] = new Rectangle(0, 0, Width, Height / 2);
81 tbr[1] = new Rectangle(0, Height / 2, Width, Height);
82 }
83 else
84 {
85 tbr[0] = new Rectangle(0, 0, Width / 2, Height);
86 tbr[1] = new Rectangle(Width / 2, 0, Width, Height);
87 }
88 }
89 else if (divisions == 3)
90 {
91 if (isVertical)
92 {
93 tbr[0] = new Rectangle(0, 0, Width / 2, 2 * Height / 3);
94 tbr[1] = new Rectangle(Width / 2, 0, Width, 2 * Height / 3);
95 tbr[2] = new Rectangle(0, 2 * Height / 3, Width, Height);
96 }
97 else
98 {
99 tbr[0] = new Rectangle(0, 0, 2 * Width / 3, Height / 2);
100 tbr[1] = new Rectangle(0, Height / 2, 2 * Width / 3, Height);
101 tbr[2] = new Rectangle(2 * Width / 3, 0, Width, Height);
102 }
103 }
104 else if (divisions == 5)
105 {
106 if (isVertical)
107 {
108 tbr[0] = new Rectangle(0, 0, Width / 2, 2 * Height / 5);
109 tbr[1] = new Rectangle(Width / 2, 0, Width, 2 * Height / 5);
110 tbr[2] = new Rectangle(0, 2 * Height / 5, Width / 2, 4 * Height / 5);
111 tbr[3] = new Rectangle(Width / 2, 2 * Height / 5, Width, 4 * Height / 5);
112 tbr[4] = new Rectangle(0, 4 * Height / 5, Width, Height);
113 }
114 else
115 {
116 tbr[0] = new Rectangle(0, 0, 2 * Width / 5, Height / 2);
117 tbr[1] = new Rectangle(0, Height / 2, 2 * Width / 5, Height);
118 tbr[2] = new Rectangle(2 * Width / 5, 0, 4 * Width / 5, Height / 2);
119 tbr[3] = new Rectangle(2 * Width / 5, Height / 2, 4 * Width / 5, Height);
120 tbr[4] = new Rectangle(4 * Width / 5, 0, Width, Height);
121 }
122 }
123 else if (divisions == 7)
124 {
125 if (isVertical)
126 {
127 tbr[0] = new Rectangle(0, 0, Width / 2, 2 * Height / 7);
128 tbr[1] = new Rectangle(Width / 2, 0, Width, 2 * Height / 7);
129 tbr[2] = new Rectangle(0, 2 * Height / 7, Width / 2, 4 * Height / 7);
130 tbr[3] = new Rectangle(Width / 2, 2 * Height / 7, Width, 4 * Height / 7);
131 tbr[4] = new Rectangle(0, 4 * Height / 7, Width / 2, 6 * Height / 7);
132 tbr[5] = new Rectangle(Width / 2, 4 * Height / 7, Width, 6 * Height / 7);
133 tbr[6] = new Rectangle(0, 6 * Height / 7, Width, Height);
134 }
135 else
136 {
137 tbr[0] = new Rectangle(0, 0, 2 * Width / 7, Height / 2);
138 tbr[1] = new Rectangle(0, Height / 2, 2 * Width / 7, Height);
139 tbr[2] = new Rectangle(2 * Width / 7, 0, 4 * Width / 7, Height / 2);
140 tbr[3] = new Rectangle(2 * Width / 7, Height / 2, 4 * Width / 7, Height);
141 tbr[4] = new Rectangle(4 * Width / 7, 0, 6 * Width / 7, Height / 2);
142 tbr[5] = new Rectangle(4 * Width / 7, Height / 2, 6 * Width / 7, Height);
143 tbr[6] = new Rectangle(6 * Width / 7, 0, Width, Height);
144 }
145 }
146 else
147 {
148 for (int divisorInd = 0; divisorInd < Utils.AcceptableDivisors.Length; divisorInd++)
149 {
150 if (divisions % Utils.AcceptableDivisors[divisorInd] == 0)
151 {
152 Rectangle[] largerDivisions = this.Split(divisions / Utils.AcceptableDivisors[divisorInd]);
153
154 int pos = 0;
155
156 for (int i = 0; i < largerDivisions.Length; i++)
157 {
158 Size s = new Size(largerDivisions[i].Width, largerDivisions[i].Height);
159 Rectangle[] currDivision = s.Split(Utils.AcceptableDivisors[divisorInd]);
160
161 for (int j = 0; j < currDivision.Length; j++)
162 {
163 tbr[pos] = new Rectangle(largerDivisions[i].X0 + currDivision[j].X0, largerDivisions[i].Y0 + currDivision[j].Y0, largerDivisions[i].X0 + currDivision[j].X1, largerDivisions[i].Y0 + currDivision[j].Y1);
164 pos++;
165 }
166 }
167
168 break;
169 }
170 }
171 }
172
173 return tbr;
174
175 }
176 }
177
178 /// <summary>
179 /// Represents the size of a rectangle using only integer numbers.
180 /// </summary>
181 public struct RoundedSize
182 {
183 /// <summary>
184 /// The width of the rectangle.
185 /// </summary>
186 public int Width;
187
188 /// <summary>
189 /// The height of the rectangle.
190 /// </summary>
191 public int Height;
192
193 /// <summary>
194 /// Create a new <see cref="RoundedSize"/> with the specified width and height.
195 /// </summary>
196 /// <param name="width">The width of the rectangle.</param>
197 /// <param name="height">The height of the rectangle.</param>
198 public RoundedSize(int width, int height)
199 {
200 Width = width;
201 Height = height;
202 }
203
204 /// <summary>
205 /// Split the size into the specified number of <see cref="RoundedRectangle"/>s.
206 /// </summary>
207 /// <param name="divisions">The number of rectangles in which the size should be split. This must be factorisable using only powers of 2, 3, 5 or 7. Otherwise, the biggest number smaller than <paramref name="divisions"/> that satisfies this condition is used.</param>
208 /// <returns>An array of <see cref="RoundedRectangle"/>s that when positioned properly cover an area of the size of this object.</returns>
209 public RoundedRectangle[] Split(int divisions)
210 {
211 divisions = Utils.GetAcceptableNumber(divisions);
212
213 RoundedRectangle[] tbr = new RoundedRectangle[divisions];
214
215 bool isVertical = this.Height > this.Width;
216
217 if (divisions == 1)
218 {
219 tbr[0] = new RoundedRectangle(0, 0, Width, Height);
220 }
221 else if (divisions == 2)
222 {
223 if (isVertical)
224 {
225 tbr[0] = new RoundedRectangle(0, 0, Width, Height / 2);
226 tbr[1] = new RoundedRectangle(0, Height / 2, Width, Height);
227 }
228 else
229 {
230 tbr[0] = new RoundedRectangle(0, 0, Width / 2, Height);
231 tbr[1] = new RoundedRectangle(Width / 2, 0, Width, Height);
232 }
233 }
234 else if (divisions == 3)
235 {
236 if (isVertical)
237 {
238 tbr[0] = new RoundedRectangle(0, 0, Width / 2, 2 * Height / 3);
239 tbr[1] = new RoundedRectangle(Width / 2, 0, Width, 2 * Height / 3);
240 tbr[2] = new RoundedRectangle(0, 2 * Height / 3, Width, Height);
241 }
242 else
243 {
244 tbr[0] = new RoundedRectangle(0, 0, 2 * Width / 3, Height / 2);
245 tbr[1] = new RoundedRectangle(0, Height / 2, 2 * Width / 3, Height);
246 tbr[2] = new RoundedRectangle(2 * Width / 3, 0, Width, Height);
247 }
248 }
249 else if (divisions == 5)
250 {
251 if (isVertical)
252 {
253 tbr[0] = new RoundedRectangle(0, 0, Width / 2, 2 * Height / 5);
254 tbr[1] = new RoundedRectangle(Width / 2, 0, Width, 2 * Height / 5);
255 tbr[2] = new RoundedRectangle(0, 2 * Height / 5, Width / 2, 4 * Height / 5);
256 tbr[3] = new RoundedRectangle(Width / 2, 2 * Height / 5, Width, 4 * Height / 5);
257 tbr[4] = new RoundedRectangle(0, 4 * Height / 5, Width, Height);
258 }
259 else
260 {
261 tbr[0] = new RoundedRectangle(0, 0, 2 * Width / 5, Height / 2);
262 tbr[1] = new RoundedRectangle(0, Height / 2, 2 * Width / 5, Height);
263 tbr[2] = new RoundedRectangle(2 * Width / 5, 0, 4 * Width / 5, Height / 2);
264 tbr[3] = new RoundedRectangle(2 * Width / 5, Height / 2, 4 * Width / 5, Height);
265 tbr[4] = new RoundedRectangle(4 * Width / 5, 0, Width, Height);
266 }
267 }
268 else if (divisions == 7)
269 {
270 if (isVertical)
271 {
272 tbr[0] = new RoundedRectangle(0, 0, Width / 2, 2 * Height / 7);
273 tbr[1] = new RoundedRectangle(Width / 2, 0, Width, 2 * Height / 7);
274 tbr[2] = new RoundedRectangle(0, 2 * Height / 7, Width / 2, 4 * Height / 7);
275 tbr[3] = new RoundedRectangle(Width / 2, 2 * Height / 7, Width, 4 * Height / 7);
276 tbr[4] = new RoundedRectangle(0, 4 * Height / 7, Width / 2, 6 * Height / 7);
277 tbr[5] = new RoundedRectangle(Width / 2, 4 * Height / 7, Width, 6 * Height / 7);
278 tbr[6] = new RoundedRectangle(0, 6 * Height / 7, Width, Height);
279 }
280 else
281 {
282 tbr[0] = new RoundedRectangle(0, 0, 2 * Width / 7, Height / 2);
283 tbr[1] = new RoundedRectangle(0, Height / 2, 2 * Width / 7, Height);
284 tbr[2] = new RoundedRectangle(2 * Width / 7, 0, 4 * Width / 7, Height / 2);
285 tbr[3] = new RoundedRectangle(2 * Width / 7, Height / 2, 4 * Width / 7, Height);
286 tbr[4] = new RoundedRectangle(4 * Width / 7, 0, 6 * Width / 7, Height / 2);
287 tbr[5] = new RoundedRectangle(4 * Width / 7, Height / 2, 6 * Width / 7, Height);
288 tbr[6] = new RoundedRectangle(6 * Width / 7, 0, Width, Height);
289 }
290 }
291 else
292 {
293 for (int divisorInd = 0; divisorInd < Utils.AcceptableDivisors.Length; divisorInd++)
294 {
295 if (divisions % Utils.AcceptableDivisors[divisorInd] == 0)
296 {
297 RoundedRectangle[] largerDivisions = this.Split(divisions / Utils.AcceptableDivisors[divisorInd]);
298
299 int pos = 0;
300
301 for (int i = 0; i < largerDivisions.Length; i++)
302 {
303 RoundedSize s = new RoundedSize(largerDivisions[i].Width, largerDivisions[i].Height);
304 RoundedRectangle[] currDivision = s.Split(Utils.AcceptableDivisors[divisorInd]);
305
306 for (int j = 0; j < currDivision.Length; j++)
307 {
308 tbr[pos] = new RoundedRectangle(largerDivisions[i].X0 + currDivision[j].X0, largerDivisions[i].Y0 + currDivision[j].Y0, largerDivisions[i].X0 + currDivision[j].X1, largerDivisions[i].Y0 + currDivision[j].Y1);
309 pos++;
310 }
311 }
312
313 break;
314 }
315 }
316 }
317
318 return tbr;
319
320 }
321 }
322
323 /// <summary>
324 /// Represents a rectangle.
325 /// </summary>
326 public struct Rectangle
327 {
328 /// <summary>
329 /// The left coordinate of the rectangle.
330 /// </summary>
331 public float X0;
332
333 /// <summary>
334 /// The top coordinate of the rectangle.
335 /// </summary>
336 public float Y0;
337
338 /// <summary>
339 /// The right coordinate of the rectangle.
340 /// </summary>
341 public float X1;
342
343 /// <summary>
344 /// The bottom coordinate of the rectangle.
345 /// </summary>
346 public float Y1;
347
348 /// <summary>
349 /// The width of the rectangle.
350 /// </summary>
351 public float Width => X1 - X0;
352
353 /// <summary>
354 /// The height of the rectangle.
355 /// </summary>
356 public float Height => Y1 - Y0;
357
358 /// <summary>
359 /// Create a new <see cref="Rectangle"/> from the specified coordinates.
360 /// </summary>
361 /// <param name="x0">The left coordinate of the rectangle.</param>
362 /// <param name="y0">The top coordinate of the rectangle.</param>
363 /// <param name="x1">The right coordinate of the rectangle.</param>
364 /// <param name="y1">The bottom coordinate of the rectangle.</param>
365 public Rectangle(float x0, float y0, float x1, float y1)
366 {
367 X0 = x0;
368 Y0 = y0;
369 X1 = x1;
370 Y1 = y1;
371 }
372
373 /// <summary>
374 /// Create a new <see cref="Rectangle"/> from the specified coordinates.
375 /// </summary>
376 /// <param name="x0">The left coordinate of the rectangle.</param>
377 /// <param name="y0">The top coordinate of the rectangle.</param>
378 /// <param name="x1">The right coordinate of the rectangle.</param>
379 /// <param name="y1">The bottom coordinate of the rectangle.</param>
380 public Rectangle(double x0, double y0, double x1, double y1)
381 {
382 X0 = (float)x0;
383 Y0 = (float)y0;
384 X1 = (float)x1;
385 Y1 = (float)y1;
386 }
387
388 /// <summary>
389 /// Round the rectangle's coordinates to the closest integers.
390 /// </summary>
391 /// <returns>A <see cref="RoundedRectangle"/> with the rounded coordinates.</returns>
393 {
394 return new RoundedRectangle(
395 (int)Math.Floor(X0 + 0.001),
396 (int)Math.Floor(Y0 + 0.001),
397 (int)Math.Ceiling(X1 - 0.001),
398 (int)Math.Ceiling(Y1 - 0.001)
399 );
400 }
401
402 /// <summary>
403 /// Round the rectangle's coordinates to the closest integers, applying the specified zoom factor.
404 /// </summary>
405 /// <param name="zoom">The zoom factor to apply.</param>
406 /// <returns>A <see cref="RoundedRectangle"/> with the rounded coordinates.</returns>
407 public RoundedRectangle Round(double zoom)
408 {
409 return new RoundedRectangle(
410 (int)Math.Floor(X0 * (float)zoom + 0.001),
411 (int)Math.Floor(Y0 * (float)zoom + 0.001),
412 (int)Math.Ceiling(X1 * (float)zoom - 0.001),
413 (int)Math.Ceiling(Y1 * (float)zoom - 0.001)
414 );
415 }
416
417 /// <summary>
418 /// Split the rectangle into the specified number of <see cref="Rectangle"/>s.
419 /// </summary>
420 /// <param name="divisions">The number of rectangles in which the rectangle should be split. This must be factorisable using only powers of 2, 3, 5 or 7. Otherwise, the biggest number smaller than <paramref name="divisions"/> that satisfies this condition is used.</param>
421 /// <returns>An array of <see cref="Rectangle"/>s that when positioned properly cover the same area as this object.</returns>
422 public Rectangle[] Split(int divisions)
423 {
424 Size s = new Size(this.Width, this.Height);
425
426 Rectangle[] splitSize = s.Split(divisions);
427
428 Rectangle[] tbr = new Rectangle[divisions];
429
430 for (int i = 0; i < splitSize.Length; i++)
431 {
432 tbr[i] = new Rectangle(this.X0 + splitSize[i].X0, this.Y0 + splitSize[i].Y0, this.X0 + splitSize[i].X1, this.Y0 + splitSize[i].Y1);
433 }
434
435 return tbr;
436 }
437
438 /// <summary>
439 /// Compute the intersection between this <see cref="Rectangle"/> and another one.
440 /// </summary>
441 /// <param name="other">The other <see cref="Rectangle"/> to intersect with this instance.</param>
442 /// <returns>The intersection between the two <see cref="Rectangle"/>s.</returns>
444 {
445 float x0 = Math.Max(this.X0, other.X0);
446 float y0 = Math.Max(this.Y0, other.Y0);
447
448 float x1 = Math.Min(this.X1, other.X1);
449 float y1 = Math.Min(this.Y1, other.Y1);
450
451 if (x1 <= x0 || y1 <= y0)
452 {
453 return new Rectangle(0, 0, 0, 0);
454 }
455 else
456 {
457 return new Rectangle(x0, y0, x1, y1);
458 }
459 }
460
461 /// <summary>
462 /// Checks whether this <see cref="Rectangle"/> contains another <see cref="Rectangle"/>.
463 /// </summary>
464 /// <param name="other">The <see cref="Rectangle"/> to check.</param>
465 /// <returns>A boolean value indicating whether this <see cref="Rectangle"/> contains the <paramref name="other"/> <see cref="Rectangle"/>.</returns>
466 public bool Contains(Rectangle other)
467 {
468 return other.X0 >= this.X0 && other.X1 <= this.X1 && other.Y0 >= this.Y0 && other.Y1 <= this.Y1;
469 }
470
471 /// <summary>
472 /// Checks whether this <see cref="Rectangle"/> contains a <see cref="PointF"/>.
473 /// </summary>
474 /// <param name="point">The <see cref="PointF"/> to check.</param>
475 /// <returns>A boolean value indicating whether this <see cref="Rectangle"/> contains the <paramref name="point"/>.</returns>
476 public bool Contains(PointF point)
477 {
478 return point.X >= this.X0 && point.X <= this.X1 && point.Y >= this.Y0 && point.Y <= this.Y1;
479 }
480
481 /// <summary>
482 /// Converts the <see cref="Rectangle"/> to a <see cref="Quad"/>.
483 /// </summary>
484 /// <returns>A <see cref="Quad"/> corresponding to the current <see cref="Rectangle"/>.</returns>
485 public Quad ToQuad()
486 {
487 return new Quad(new PointF(X0, Y1), new PointF(X0, Y0), new PointF(X1, Y0), new PointF(X1, Y1));
488 }
489 }
490
491 /// <summary>
492 /// Represents a rectangle using only integer numbers.
493 /// </summary>
494 public struct RoundedRectangle
495 {
496 /// <summary>
497 /// The left coordinate of the rectangle.
498 /// </summary>
499 public int X0;
500
501 /// <summary>
502 /// The top coordinate of the rectangle.
503 /// </summary>
504 public int Y0;
505
506 /// <summary>
507 /// The right coordinate of the rectangle.
508 /// </summary>
509 public int X1;
510
511 /// <summary>
512 /// The bottom coordinate of the rectangle.
513 /// </summary>
514 public int Y1;
515
516 /// <summary>
517 /// The width of the rectangle.
518 /// </summary>
519 public int Width => X1 - X0;
520
521 /// <summary>
522 /// The height of the rectangle.
523 /// </summary>
524 public int Height => Y1 - Y0;
525
526 /// <summary>
527 /// Create a new <see cref="RoundedRectangle"/> from the specified coordinates.
528 /// </summary>
529 /// <param name="x0">The left coordinate of the rectangle.</param>
530 /// <param name="y0">The top coordinate of the rectangle.</param>
531 /// <param name="x1">The right coordinate of the rectangle.</param>
532 /// <param name="y1">The bottom coordinate of the rectangle.</param>
533 public RoundedRectangle(int x0, int y0, int x1, int y1)
534 {
535 X0 = x0;
536 Y0 = y0;
537 X1 = x1;
538 Y1 = y1;
539 }
540
541 /// <summary>
542 /// Split the rectangle into the specified number of <see cref="RoundedRectangle"/>s.
543 /// </summary>
544 /// <param name="divisions">The number of rectangles in which the rectangle should be split. This must be factorisable using only powers of 2, 3, 5 or 7. Otherwise, the biggest number smaller than <paramref name="divisions"/> that satisfies this condition is used.</param>
545 /// <returns>An array of <see cref="RoundedRectangle"/>s that when positioned properly cover the same area as this object.</returns>
546 public RoundedRectangle[] Split(int divisions)
547 {
548 RoundedSize s = new RoundedSize(this.Width, this.Height);
549
550 RoundedRectangle[] splitSize = s.Split(divisions);
551
552 RoundedRectangle[] tbr = new RoundedRectangle[divisions];
553
554 for (int i = 0; i < splitSize.Length; i++)
555 {
556 tbr[i] = new RoundedRectangle(this.X0 + splitSize[i].X0, this.Y0 + splitSize[i].Y0, this.X0 + splitSize[i].X1, this.Y0 + splitSize[i].Y1);
557 }
558
559 return tbr;
560 }
561 }
562
563 /// <summary>
564 /// Represents a point.
565 /// </summary>
566 public struct PointF
567 {
568 /// <summary>
569 /// The horizontal coordinate of the point.
570 /// </summary>
571 public float X;
572
573 /// <summary>
574 /// The vertical coordinate of the point.
575 /// </summary>
576 public float Y;
577
578 /// <summary>
579 /// Create a new <see cref="PointF"/> from the specified coordinates.
580 /// </summary>
581 /// <param name="x">The horizontal coordinate of the point.</param>
582 /// <param name="y">The vertical coordinate of the point.</param>
583 public PointF(float x, float y)
584 {
585 X = x;
586 Y = y;
587 }
588 }
589
590 /// <summary>
591 /// Represents a quadrilater (not necessarily a rectangle).
592 /// </summary>
593 public struct Quad
594 {
595 /// <summary>
596 /// The lower left point of the quadrilater.
597 /// </summary>
599
600 /// <summary>
601 /// The upper left point of the quadrilater.
602 /// </summary>
604
605 /// <summary>
606 /// The upper right point of the quadrilater.
607 /// </summary>
609
610 /// <summary>
611 /// The lower right point of the quadrilater.
612 /// </summary>
614
615 /// <summary>
616 /// Creates a new <see cref="Quad"/> from the specified points.
617 /// </summary>
618 /// <param name="lowerLeft">The lower left point of the quadrilater.</param>
619 /// <param name="upperLeft">The upper left point of the quadrilater.</param>
620 /// <param name="upperRight">The upper right point of the quadrilater.</param>
621 /// <param name="lowerRight">The lower right point of the quadrilater.</param>
622 public Quad(PointF lowerLeft, PointF upperLeft, PointF upperRight, PointF lowerRight)
623 {
624 this.LowerLeft = lowerLeft;
625 this.UpperLeft = upperLeft;
626 this.UpperRight = upperRight;
627 this.LowerRight = lowerRight;
628 }
629
630 /// <summary>
631 /// Checks whether this <see cref="Quad"/> contains a <see cref="PointF"/>.
632 /// </summary>
633 /// <param name="point">The <see cref="PointF"/> to check.</param>
634 /// <returns>A boolean value indicating whether this <see cref="Quad"/> contains the <paramref name="point"/>.</returns>
635 public bool Contains(PointF point)
636 {
637 return PointInTriangle(point, this.LowerLeft, this.UpperLeft, this.UpperRight) || PointInTriangle(point, this.LowerLeft, this.UpperRight, this.LowerRight);
638 }
639
640 /// <summary>
641 /// Checks whether a point is contained in a triangle.
642 /// </summary>
643 /// <param name="pt">The point to test.</param>
644 /// <param name="A">The first vertex of the triangle.</param>
645 /// <param name="B">The second vertex of the triangle.</param>
646 /// <param name="C">The third vertex of the triangle.</param>
647 /// <returns>A boolean value indicating whether the point is contained in the triangle.</returns>
648 private static bool PointInTriangle(PointF pt, PointF A, PointF B, PointF C)
649 {
650 double signAB = (pt.X - B.X) * (A.Y - B.Y) - (A.X - B.X) * (pt.Y - B.Y);
651 double signBC = (pt.X - C.X) * (B.Y - C.Y) - (B.X - C.X) * (pt.Y - C.Y);
652 double signCA = (pt.X - A.X) * (C.Y - A.Y) - (C.X - A.X) * (pt.Y - A.Y);
653
654 return !((signAB < 0 || signBC < 0 || signCA < 0) && (signAB > 0 || signBC > 0 || signCA > 0));
655 }
656 }
657}
Represents a point.
Definition: Rectangles.cs:567
float X
The horizontal coordinate of the point.
Definition: Rectangles.cs:571
PointF(float x, float y)
Create a new PointF from the specified coordinates.
Definition: Rectangles.cs:583
float Y
The vertical coordinate of the point.
Definition: Rectangles.cs:576
Represents a quadrilater (not necessarily a rectangle).
Definition: Rectangles.cs:594
Quad(PointF lowerLeft, PointF upperLeft, PointF upperRight, PointF lowerRight)
Creates a new Quad from the specified points.
Definition: Rectangles.cs:622
PointF LowerLeft
The lower left point of the quadrilater.
Definition: Rectangles.cs:598
bool Contains(PointF point)
Checks whether this Quad contains a PointF.
Definition: Rectangles.cs:635
PointF LowerRight
The lower right point of the quadrilater.
Definition: Rectangles.cs:613
PointF UpperRight
The upper right point of the quadrilater.
Definition: Rectangles.cs:608
PointF UpperLeft
The upper left point of the quadrilater.
Definition: Rectangles.cs:603
Represents a rectangle.
Definition: Rectangles.cs:327
RoundedRectangle Round()
Round the rectangle's coordinates to the closest integers.
Definition: Rectangles.cs:392
Quad ToQuad()
Converts the Rectangle to a Quad.
Definition: Rectangles.cs:485
bool Contains(PointF point)
Checks whether this Rectangle contains a PointF.
Definition: Rectangles.cs:476
Rectangle(float x0, float y0, float x1, float y1)
Create a new Rectangle from the specified coordinates.
Definition: Rectangles.cs:365
float Width
The width of the rectangle.
Definition: Rectangles.cs:351
Rectangle Intersect(Rectangle other)
Compute the intersection between this Rectangle and another one.
Definition: Rectangles.cs:443
float Height
The height of the rectangle.
Definition: Rectangles.cs:356
RoundedRectangle Round(double zoom)
Round the rectangle's coordinates to the closest integers, applying the specified zoom factor.
Definition: Rectangles.cs:407
float Y0
The top coordinate of the rectangle.
Definition: Rectangles.cs:336
float X1
The right coordinate of the rectangle.
Definition: Rectangles.cs:341
float X0
The left coordinate of the rectangle.
Definition: Rectangles.cs:331
bool Contains(Rectangle other)
Checks whether this Rectangle contains another Rectangle.
Definition: Rectangles.cs:466
float Y1
The bottom coordinate of the rectangle.
Definition: Rectangles.cs:346
Rectangle(double x0, double y0, double x1, double y1)
Create a new Rectangle from the specified coordinates.
Definition: Rectangles.cs:380
Rectangle[] Split(int divisions)
Split the rectangle into the specified number of Rectangles.
Definition: Rectangles.cs:422
Represents a rectangle using only integer numbers.
Definition: Rectangles.cs:495
int Y1
The bottom coordinate of the rectangle.
Definition: Rectangles.cs:514
int Width
The width of the rectangle.
Definition: Rectangles.cs:519
int X1
The right coordinate of the rectangle.
Definition: Rectangles.cs:509
RoundedRectangle(int x0, int y0, int x1, int y1)
Create a new RoundedRectangle from the specified coordinates.
Definition: Rectangles.cs:533
int Height
The height of the rectangle.
Definition: Rectangles.cs:524
RoundedRectangle[] Split(int divisions)
Split the rectangle into the specified number of RoundedRectangles.
Definition: Rectangles.cs:546
int Y0
The top coordinate of the rectangle.
Definition: Rectangles.cs:504
int X0
The left coordinate of the rectangle.
Definition: Rectangles.cs:499
Represents the size of a rectangle using only integer numbers.
Definition: Rectangles.cs:182
int Height
The height of the rectangle.
Definition: Rectangles.cs:191
RoundedSize(int width, int height)
Create a new RoundedSize with the specified width and height.
Definition: Rectangles.cs:198
int Width
The width of the rectangle.
Definition: Rectangles.cs:186
RoundedRectangle[] Split(int divisions)
Split the size into the specified number of RoundedRectangles.
Definition: Rectangles.cs:209
Represents the size of a rectangle.
Definition: Rectangles.cs:26
Size(double width, double height)
Create a new Size with the specified width and height.
Definition: Rectangles.cs:53
float Width
The width of the rectangle.
Definition: Rectangles.cs:30
Size(float width, float height)
Create a new Size with the specified width and height.
Definition: Rectangles.cs:42
Rectangle[] Split(int divisions)
Split the size into the specified number of Rectangles.
Definition: Rectangles.cs:64
float Height
The height of the rectangle.
Definition: Rectangles.cs:35