3template < prototype_rectangle RECTANGLE_TYPE >
4RECTANGLE_TYPE & clear(RECTANGLE_TYPE & rectangle);
241template < prototype_po
int POINT1, prototype_po
int POINT2 >
242::f64 f64_distance(
const POINT1 & point1,
const POINT2 & point2)
245 return sqrt((point2.x - point1.x) * (point2.x - point1.x) + (point2.y - point1.y) * (point2.y - point1.y));
250template <
typename X,
typename Y >
251inline auto get_dimension(enum_orientation eorientation, X x, Y y)
254 if (eorientation == e_orientation_horizontal)
260 else if (eorientation == e_orientation_vertical)
269 throw ::exception(error_bad_argument,
"invalid orientation");
276template <
typename X,
typename Y,
typename Z >
277inline auto get_dimension(enum_orientation eorientation, X x, Y y, Z z)
280 if (eorientation == e_orientation_horizontal)
286 else if (eorientation == e_orientation_vertical)
292 else if (eorientation == e_orientation_z)
301 throw ::exception(error_bad_argument,
"invalid orientation (2)");
308template <
typename X,
typename Y,
typename Z,
typename W >
309inline auto get_dimension(enum_orientation eorientation, X x, Y y, Z z, W w)
312 if (eorientation == e_orientation_horizontal)
318 else if (eorientation == e_orientation_vertical)
324 else if (eorientation == e_orientation_z)
330 else if (eorientation == e_orientation_w)
339 throw ::exception(error_bad_argument,
"invalid orientation (3)");
346template <
typename X,
typename Y >
347inline auto get_normal_dimension2(enum_orientation eorientation, X x, Y y)
350 if (eorientation == e_orientation_horizontal)
356 else if (eorientation == e_orientation_vertical)
365 throw ::exception(error_bad_argument,
"invalid orientation (4)");
415template < prototype_rectangle RECTANGLE1, prototype_rectangle RECTANGLE2 >
416RECTANGLE1 & unite(RECTANGLE1 & rectangle1,
const RECTANGLE2 & rectangle2)
419 if (is_empty(rectangle1))
422 if (is_empty(rectangle2))
431 copy(rectangle1, rectangle2);
436 else if (is_set(rectangle2))
439 rectangle2.expand_bounding_box(rectangle1.top_left(), rectangle1.bottom_right());
450template < prototype_rectangle RECTANGLE_TYPE >
451constexpr auto width(RECTANGLE_TYPE & rectangle) {
return rectangle.right - rectangle.left; }
454template < prototype_rectangle RECTANGLE_TYPE >
455constexpr auto height(RECTANGLE_TYPE & rectangle) {
return rectangle.bottom - rectangle.top; }
458template <
typename W,
typename H >
459constexpr H area(W w, H h) {
return (w <= (W)0 || h <= (H)0) ? 0 : (H)(w * h); }
462template < prototype_rectangle RECTANGLE_TYPE >
463constexpr auto area(RECTANGLE_TYPE & rectangle) {
return area(width(rectangle), height(rectangle)); }
466template < prototype_rectangle RECTANGLE_TYPE >
467bool is_null(
const RECTANGLE_TYPE & rectangle)
470 return rectangle.left == (
decltype(rectangle.left))0
471 && rectangle.top == (
decltype(rectangle.top))0
472 && rectangle.right == (
decltype(rectangle.right))0
473 && rectangle.bottom == (
decltype(rectangle.bottom))0;
478template < prototype_rectangle RECTANGLE_TYPE >
479constexpr auto is_empty(RECTANGLE_TYPE & rectangle) { return ::is_null(rectangle) || rectangle.right <= rectangle.left || rectangle.bottom <= rectangle.top; }
482template < prototype_rectangle RECTANGLE_TYPE >
483constexpr auto is_set(RECTANGLE_TYPE & rectangle) {
return !::is_empty(rectangle); }
486template < prototype_size SIZE_TYPE >
487bool is_null(
const SIZE_TYPE & size)
490 return size.cx == (
typename SIZE_TYPE::UNIT_TYPE)0
491 && size.cy == (
typename SIZE_TYPE::UNIT_TYPE)0;
496template < prototype_po
int POINT_TYPE >
497bool is_null(
const POINT_TYPE & point)
500 return point.x == (
typename POINT_TYPE::UNIT_TYPE)0 && point.y == (
typename POINT_TYPE::UNIT_TYPE)0;
508template < prototype_rectangle RECTANGLE_TYPE,
typename X >
509inline RECTANGLE_TYPE & x_offset(RECTANGLE_TYPE & rectangle, X x)
512 rectangle.left = (decay<typename RECTANGLE_TYPE::UNIT_TYPE>)(rectangle.left + x);
514 rectangle.right = (decay<typename RECTANGLE_TYPE::UNIT_TYPE>)(rectangle.right + x);
521template < prototype_rectangle RECTANGLE_TYPE,
typename Y >
522inline RECTANGLE_TYPE & y_offset(RECTANGLE_TYPE & rectangle, Y y)
525 rectangle.top = (decay<typename RECTANGLE_TYPE::UNIT_TYPE>)(rectangle.top + y);
527 rectangle.bottom = (decay<typename RECTANGLE_TYPE::UNIT_TYPE>)(rectangle.bottom + y);
535template < prototype_rectangle RECTANGLE_TYPE, prototype_number X >
536inline RECTANGLE_TYPE & x_subtract(RECTANGLE_TYPE & rectangle, X x)
539 rectangle.left = (::decay<typename RECTANGLE_TYPE::UNIT_TYPE>)(rectangle.left - x);
541 rectangle.right = (::decay<typename RECTANGLE_TYPE::UNIT_TYPE>)(rectangle.right - x);
548template < prototype_rectangle RECTANGLE_TYPE, prototype_number Y >
549inline RECTANGLE_TYPE & y_subtract(RECTANGLE_TYPE & rectangle, Y y)
552 rectangle.top = (::decay<typename RECTANGLE_TYPE::UNIT_TYPE>)(rectangle.top - y);
554 rectangle.bottom = (::decay<typename RECTANGLE_TYPE::UNIT_TYPE>)(rectangle.bottom - y);
561template < prototype_rectangle RECTANGLE_TYPE, prototype_number X, prototype_number Y >
562inline RECTANGLE_TYPE & offset(RECTANGLE_TYPE & rectangle, X x, Y y)
565 x_offset(rectangle, x);
567 y_offset(rectangle, y);
574template < prototype_rectangle RECTANGLE_TYPE, prototype_number X, prototype_number Y >
575inline RECTANGLE_TYPE & subtract(RECTANGLE_TYPE & rectangle, X x, Y y)
578 x_subtract(rectangle, x);
580 y_subtract(rectangle, y);
587template < prototype_rectangle RECTANGLE_TYPE, prototype_po
int POINT_TYPE >
588inline RECTANGLE_TYPE & offset(RECTANGLE_TYPE & rectangle,
const POINT_TYPE & point)
591 return offset(rectangle, point.x, point.y);
596template < prototype_rectangle RECTANGLE_TYPE, prototype_po
int POINT_TYPE >
597inline RECTANGLE_TYPE & subtract(RECTANGLE_TYPE & rectangle,
const POINT_TYPE & point)
600 return subtract(rectangle, point.x, point.y);
605template < prototype_rectangle RECTANGLE1, prototype_rectangle RECTANGLE2 >
606inline RECTANGLE1 & subtract(RECTANGLE1 & rectangle,
const RECTANGLE2 & rectangle2)
609 rectangle.left = (decay<typename RECTANGLE1::UNIT_TYPE>)(rectangle.left - rectangle2.left);
610 rectangle.top = (decay<typename RECTANGLE1::UNIT_TYPE>)(rectangle.top - rectangle2.top);
611 rectangle.right = (decay<typename RECTANGLE1::UNIT_TYPE>)(rectangle.right - rectangle2.right);
612 rectangle.bottom = (decay<typename RECTANGLE1::UNIT_TYPE>)(rectangle.bottom - rectangle2.bottom);
619template < prototype_rectangle RECTANGLE, prototype_rectangle RECTANGLE1, prototype_rectangle RECTANGLE2 >
620inline RECTANGLE & subtract(RECTANGLE & rectangle,
const RECTANGLE1 & rectangle1,
const RECTANGLE2 & rectangle2)
623 rectangle.left = (decay<typename RECTANGLE::UNIT_TYPE>)(rectangle1.left - rectangle2.left);
624 rectangle.top = (decay<typename RECTANGLE::UNIT_TYPE>)(rectangle1.top - rectangle2.top);
625 rectangle.right = (decay<typename RECTANGLE::UNIT_TYPE>)(rectangle1.right - rectangle2.right);
626 rectangle.bottom = (decay<typename RECTANGLE::UNIT_TYPE>)(rectangle1.bottom - rectangle2.bottom);
637template < prototype_sequence2 SEQUENCE, prototype_number X, prototype_number Y >
638inline SEQUENCE & offset(SEQUENCE & sequence, X x, Y y)
642 sequence.x = (
const decay<typename SEQUENCE::UNIT_TYPE>&)(sequence.x + x);
643 sequence.y = (
const decay<typename SEQUENCE::UNIT_TYPE>&)(sequence.y + y);
650template < prototype_sequence2 SEQUENCEA, prototype_sequence SEQUENCEB >
651inline SEQUENCEA & offset(SEQUENCEA & sequencea,
const SEQUENCEB & sequenceb)
655 return offset(sequencea, sequenceb.x, sequenceb.y);
660template < prototype_sequence2 SEQUENCEA, prototype_sequence SEQUENCEB >
661inline SEQUENCEA & add(SEQUENCEA & sequencea,
const SEQUENCEB & sequenceb)
665 return offset(sequencea, sequenceb);
670template < prototype_sequence2 SEQUENCE,
typename X,
typename Y >
671inline SEQUENCE & subtract(SEQUENCE & sequence, X x, Y y)
675 sequence.x = (
const decay<typename SEQUENCE::UNIT_TYPE>&)(sequence.x - x);
676 sequence.y = (
const decay<typename SEQUENCE::UNIT_TYPE>&)(sequence.y - y);
683template < prototype_sequence2 SEQUENCEA, prototype_sequence2 SEQUENCEB >
684inline SEQUENCEA & subtract(SEQUENCEA & sequence,
const SEQUENCEB & sequenceb)
688 return subtract(sequence, sequenceb.x, sequenceb.y);
693template < prototype_rectangle RECTANGLE_TYPE, prototype_po
int POINT_TYPE >
694inline RECTANGLE_TYPE & add(RECTANGLE_TYPE & rectangle,
const POINT_TYPE & point)
697 return offset(rectangle, point);
702template < prototype_rectangle RECTANGLE_TYPE, prototype_rectangle RECT_TYPE1, prototype_rectangle RECT_TYPE2 >
703bool x_intersect(RECTANGLE_TYPE & rectangle,
const RECT_TYPE1 & rect1,
const RECT_TYPE2 & rect2)
706 auto left = maximum(rect1.left, rect2.left);
708 auto right = minimum(rect1.right, rect2.right);
710 bool bIntersect = right > left;
725 rectangle.left = left;
727 rectangle.right = right;
736template < prototype_rectangle RECT_TYPE1, prototype_rectangle RECT_TYPE2 >
737bool x_intersects(
const RECT_TYPE1 & rect1,
const RECT_TYPE2 & rect2)
741 return rect1.left < rect2.right && rect1.right > rect2.left;
752template < prototype_rectangle RECTANGLE_TYPE, prototype_rectangle RECT_TYPE1, prototype_rectangle RECT_TYPE2 >
753bool y_intersect(RECTANGLE_TYPE & rectangle,
const RECT_TYPE1 & rect1,
const RECT_TYPE2 & rect2)
756 auto top = maximum(rect1.top, rect2.top);
758 auto bottom = minimum(rect1.bottom, rect2.bottom);
760 bool bIntersect = bottom > top;
767 rectangle.bottom = 0;
777 rectangle.bottom = bottom;
786template < prototype_rectangle RECT_TYPE1, prototype_rectangle RECT_TYPE2 >
787bool y_intersects(
const RECT_TYPE1 & rect1,
const RECT_TYPE2 & rect2)
796 return rect1.top < rect2.bottom && rect1.bottom > rect2.top;
801template < prototype_rectangle RECTANGLE_TYPE, prototype_rectangle RECT_TYPE1, prototype_rectangle RECT_TYPE2 >
802bool intersect(RECTANGLE_TYPE & rectangle,
const RECT_TYPE1 & rect1,
const RECT_TYPE2 & rect2)
805 if (x_intersect(rectangle, rect1, rect2) && y_intersect(rectangle, rect1, rect2))
824template < prototype_rectangle RECT_TYPE1, prototype_rectangle RECT_TYPE2 >
825bool intersects(
const RECT_TYPE1 & rect1,
const RECT_TYPE2 & rect2)
828 return x_intersects(rect1, rect2) && y_intersects(rect1, rect2);
833template < prototype_rectangle RECTANGLE_TYPE, prototype_rectangle RECT_TYPE1, prototype_rectangle RECT_TYPE2 >
834bool x_null_intersect(RECTANGLE_TYPE & rectangle,
const RECT_TYPE1 & rect1,
const RECT_TYPE2 & rect2)
837 auto left = maximum(rect1.left, rect2.left);
839 auto right = minimum(rect1.right, rect2.right);
841 bool bIntersect = right >= left;
853 rectangle.left = left;
855 rectangle.right = right;
864template < prototype_rectangle RECTANGLE_TYPE, prototype_rectangle RECT_TYPE1, prototype_rectangle RECT_TYPE2 >
865bool y_null_intersect(RECTANGLE_TYPE & rectangle,
const RECT_TYPE1 & rect1,
const RECT_TYPE2 & rect2)
868 auto top = maximum(rect1.top, rect2.top);
870 auto bottom = minimum(rect1.bottom, rect2.bottom);
872 bool bIntersect = bottom >= top;
886 rectangle.bottom = bottom;
895template < prototype_rectangle RECTANGLE_TYPE, prototype_rectangle RECT_TYPE1, prototype_rectangle RECT_TYPE2 >
896bool null_intersect(RECTANGLE_TYPE & rectangle,
const RECT_TYPE1 & rect1,
const RECT_TYPE2 & rect2)
899 if (x_null_intersect(rectangle, rect1, rect2) && y_null_intersect(rectangle, rect1, rect2))
918template < prototype_rectangle RECTANGLE_TYPE, prototype_rectangle RECT_TYPE1, prototype_rectangle RECT_TYPE2 >
919bool x_left_null_intersect(RECTANGLE_TYPE & rectangle,
const RECT_TYPE1 & rect1,
const RECT_TYPE2 & rect2)
922 rectangle.left = maximum(rect1.left, rect2.left);
924 rectangle.right = minimum(rect1.right, rect2.right);
926 return rectangle.right > rectangle.left || (rectangle.right == rectangle.left && rect1.left == rect2.left);
931template < prototype_rectangle RECTANGLE_TYPE, prototype_rectangle RECT_TYPE1, prototype_rectangle RECT_TYPE2 >
932bool y_top_null_intersect(RECTANGLE_TYPE & rectangle,
const RECT_TYPE1 & rect1,
const RECT_TYPE2 & rect2)
935 rectangle.top = maximum(rect1.top, rect2.top);
937 rectangle.bottom = minimum(rect1.bottom, rect2.bottom);
939 return rectangle.top < rectangle.bottom || (rectangle.top == rectangle.bottom && rect1.top == rect2.top);
944template < prototype_rectangle RECTANGLE_TYPE, prototype_rectangle RECT_TYPE1, prototype_rectangle RECT_TYPE2 >
945bool top_left_null_intersect(RECTANGLE_TYPE & rectangle,
const RECT_TYPE1 & rect1,
const RECT_TYPE2 & rect2)
948 if (x_left_null_intersect(rectangle, rect1, rect2) && y_top_null_intersect(rectangle, rect1, rect2))
966template < prototype_rectangle RECTANGLE1, prototype_rectangle RECTANGLE2 >
967bool is_equal(
const RECTANGLE1 & rectangle1,
const RECTANGLE2 & rectangle2, largest_number < ::decay<typename RECTANGLE1::UNIT_TYPE>, ::decay<typename RECTANGLE2::UNIT_TYPE > > epsilon = default_epsilon < ::largest_number < ::decay < typename RECTANGLE1::UNIT_TYPE >, ::decay<typename RECTANGLE2::UNIT_TYPE > >>())
970 return is_equal(rectangle1.left, rectangle2.left, epsilon)
971 && is_equal(rectangle1.top, rectangle2.top, epsilon)
972 && is_equal(rectangle1.right, rectangle2.right, epsilon)
973 && is_equal(rectangle1.bottom, rectangle2.bottom, epsilon);
978template < prototype_po
int POINT1, prototype_po
int POINT2 >
979bool is_equal(
const POINT1 & point1,
const POINT2 & point2, largest_number < ::decay<typename POINT1::UNIT_TYPE>, ::decay<typename POINT2::UNIT_TYPE> > epsilon = default_epsilon<largest_number < ::decay<typename POINT1::UNIT_TYPE>, ::decay<typename POINT2::UNIT_TYPE> >>())
982 return is_equal(point1.x, point2.x, epsilon) && is_equal(point1.y, point2.y, epsilon);
987template < prototype_size SIZE1, prototype_size SIZE2 >
988bool is_equal(
const SIZE1 & size1,
const SIZE2 & size2, largest_number < ::decay<typename SIZE1::UNIT_TYPE>, ::decay<typename SIZE2::UNIT_TYPE> > epsilon = default_epsilon<largest_number < ::decay<typename SIZE1::UNIT_TYPE>, ::decay<typename SIZE2::UNIT_TYPE > >>())
991 return is_equal(size1.cx, size2.cx, epsilon) && is_equal(size1.cy, size2.cy, epsilon);
996template < prototype_rectangle RECTANGLE_TYPE, prototype_number L, prototype_number T, prototype_number R, prototype_number B >
997RECTANGLE_TYPE & assign(RECTANGLE_TYPE & rectangle, L l, T t, R r, B b)
1000 rectangle.left = (
typename RECTANGLE_TYPE::UNIT_TYPE)l;
1001 rectangle.top = (
typename RECTANGLE_TYPE::UNIT_TYPE)t;
1002 rectangle.right = (
typename RECTANGLE_TYPE::UNIT_TYPE)r;
1003 rectangle.bottom = (
typename RECTANGLE_TYPE::UNIT_TYPE)b;
1010template < prototype_rectangle RECTANGLE, prototype_number L, prototype_number T, prototype_number W, prototype_number H >
1011RECTANGLE & set_dimension(RECTANGLE & rectangle, L l, T t, W w, H h)
1014 rectangle.left = (
typename RECTANGLE::UNIT_TYPE)l;
1015 rectangle.top = (
typename RECTANGLE::UNIT_TYPE)t;
1016 rectangle.right = (
typename RECTANGLE::UNIT_TYPE)(l + w);
1017 rectangle.bottom = (
typename RECTANGLE::UNIT_TYPE)(t + h);
1033template < prototype_rectangle RECTANGLE, prototype_po
int POINT, prototype_size SIZE >
1034RECTANGLE & set_bottom_right(RECTANGLE & rectangle,
const SIZE & size)
1037 rectangle.right = (
typename RECTANGLE::UNIT_TYPE)(rectangle.left + size.cx);
1038 rectangle.bottom = (
typename RECTANGLE::UNIT_TYPE)(rectangle.top + size.cy);
1045template < prototype_rectangle RECTANGLE, prototype_po
int POINT, prototype_size SIZE >
1046RECTANGLE & assign(RECTANGLE & rectangle,
const POINT & point,
const SIZE & size)
1049 rectangle.left = (
typename RECTANGLE::UNIT_TYPE)point.x;
1050 rectangle.top = (
typename RECTANGLE::UNIT_TYPE)point.y;
1051 rectangle.right = (
typename RECTANGLE::UNIT_TYPE)(point.x + size.cx);
1052 rectangle.bottom = (
typename RECTANGLE::UNIT_TYPE)(point.y + size.cy);
1059template < prototype_rectangle RECTANGLE_TYPE >
1060RECTANGLE_TYPE & clear(RECTANGLE_TYPE & rectangle)
1063 return ::assign(rectangle, 0, 0, 0, 0);
1069template < prototype_rectangle RECTANGLE, prototype_number X >
1070inline bool contains_x(
const RECTANGLE & rectangle, X x)
1073 return x >= rectangle.left && x <= rectangle.right;
1078template < prototype_rectangle RECTANGLE, prototype_number Y >
1079inline bool contains_y(
const RECTANGLE & rectangle, Y y)
1082 return y >= rectangle.top && y <= rectangle.bottom;
1087template <
typename RECTANGLE, prototype_number X, prototype_number Y >
1088inline bool contains(
const RECTANGLE & rectangle, X x, Y y)
1091 return contains_x(rectangle, x) && contains_y(rectangle, y);
1096template < prototype_rectangle RECTANGLE_TYPE, prototype_number L, prototype_number T, prototype_number R, prototype_number B >
1097inline RECTANGLE_TYPE & inflate(RECTANGLE_TYPE & rectangle, L l, T t, R r, B b)
1100 rectangle.left = (
typename RECTANGLE_TYPE::UNIT_TYPE)(rectangle.left - l);
1101 rectangle.top = (
typename RECTANGLE_TYPE::UNIT_TYPE)(rectangle.top - t);
1102 rectangle.right = (
typename RECTANGLE_TYPE::UNIT_TYPE)(rectangle.right + r);
1103 rectangle.bottom = (
typename RECTANGLE_TYPE::UNIT_TYPE)(rectangle.bottom + b);
1110template < prototype_rectangle RECTANGLE_TYPE, prototype_rectangle RECT_TYPE2 >
1111inline RECTANGLE_TYPE & inflate(RECTANGLE_TYPE & rectangle,
const RECT_TYPE2 & rect2)
1114 return inflate(rectangle, rect2.left, rect2.top, rect2.right, rect2.bottom);
1119template < prototype_rectangle RECTANGLE_TYPE, prototype_rectangle RECT_TYPE2 >
1120inline RECTANGLE_TYPE & multiply_inline(RECTANGLE_TYPE & rectangle,
const RECT_TYPE2 & rect2)
1123 rectangle.left *= rect2.left;
1124 rectangle.top *= rect2.top;
1125 rectangle.right *= rect2.right;
1126 rectangle.bottom *= rect2.bottom;
1133template < prototype_rectangle RECTANGLE_TYPE, prototype_number L, prototype_number T, prototype_number R, prototype_number B >
1134inline RECTANGLE_TYPE & deflate(RECTANGLE_TYPE & rectangle, L l, T t, R r, B b)
1137 rectangle.left = (
typename RECTANGLE_TYPE::UNIT_TYPE)(rectangle.left + l);
1138 rectangle.top = (
typename RECTANGLE_TYPE::UNIT_TYPE)(rectangle.top + t);
1139 rectangle.right = (
typename RECTANGLE_TYPE::UNIT_TYPE)(rectangle.right - r);
1140 rectangle.bottom = (
typename RECTANGLE_TYPE::UNIT_TYPE)(rectangle.bottom - b);
1147template <
typename RECTANGLE_TYPE, prototype_rectangle RECT_TYPE2 >
1148inline RECTANGLE_TYPE & deflate(RECTANGLE_TYPE & rectangle,
const RECT_TYPE2 & rect2)
1151 return deflate(rectangle, rect2.left, rect2.top, rect2.right, rect2.bottom);
1156template < prototype_rectangle RECTANGLE_TYPE, prototype_number X, prototype_number Y >
1157inline RECTANGLE_TYPE & inflate(RECTANGLE_TYPE & rectangle, X x, Y y)
1160 return inflate(rectangle, x, y, x, y);
1164template < prototype_rectangle RECTANGLE_TYPE, prototype_number X, prototype_number Y >
1165inline RECTANGLE_TYPE & deflate(RECTANGLE_TYPE & rectangle, X x, Y y)
1168 return deflate(rectangle, x, y, x, y);
1173template < prototype_rectangle RECTANGLE_TYPE, prototype_number UNIT >
1174inline RECTANGLE_TYPE & inflate(RECTANGLE_TYPE & rectangle, UNIT u)
1177 return inflate(rectangle, u, u);
1182template < prototype_rectangle RECTANGLE_TYPE, prototype_number UNIT >
1183inline RECTANGLE_TYPE & deflate(RECTANGLE_TYPE & rectangle, UNIT u)
1186 return deflate(rectangle, u, u);
1191template < prototype_rectangle RECTANGLE_TYPE >
1192inline RECTANGLE_TYPE & swap_left_right(RECTANGLE_TYPE & rectangle) { __swap(rectangle.left, rectangle.right);
return rectangle; }
1195template < prototype_po
int POINT1, prototype_po
int POINT2 >
1196inline bool polygon_contains_winding(
const POINT1 * ppPolygon, ::i32 iCount,
const POINT2 & point)
1199 ::i32 i, j = iCount - 1;
1205 bool oddNodes =
false;
1207 for (i = 0; i < iCount; i++)
1210 if (((ppPolygon[i].y < y && ppPolygon[j].y >= y) || (ppPolygon[j].y < y && ppPolygon[i].y >= y)) && (ppPolygon[i].x <= x || ppPolygon[j].x <= x))
1213 oddNodes ^= (ppPolygon[i].x + (y - ppPolygon[i].y) / (ppPolygon[j].y - ppPolygon[i].y) * (ppPolygon[j].x - ppPolygon[i].x) < x);
1232template < prototype_po
int POINT1, prototype_po
int POINT2 >
1233inline bool polygon_contains_alternate(
const POINT1 * ppPolygon, ::i32 iCount,
const POINT2 & point,
const bool use_holes, largest_number < ::decay<typename POINT1::UNIT_TYPE>, ::decay<typename POINT2::UNIT_TYPE>> epsilon = default_epsilon<largest_number < ::decay < typename POINT1::UNIT_TYPE >, ::decay < typename POINT2::UNIT_TYPE > > > ())
1236 using UNIT_TYPE = largest_number < ::decay <typename POINT1::UNIT_TYPE >, ::decay<typename POINT2::UNIT_TYPE > >;
1239 UNIT_TYPE angletot{};
1244 auto * p1 = &ppPolygon[iCount - 1];
1246 const POINT1 * p2 =
nullptr;
1249 POINT1 fp1 = *p1 - point;
1251 for (::i32 i = 0; i < iCount; i++)
1257 POINT1 fp2 = *p2 - point;
1260 angletot += fp1.angle(fp2);
1269 angletot = (UNIT_TYPE) fabs(angletot);
1274 auto nested = (UNIT_TYPE) (floor((::f64) (angletot / (UNIT_TYPE)(MATH_PI * 2.0)) + (::f64) epsilon));
1276 angletot -= nested * (UNIT_TYPE)(MATH_PI * 2.0);
1278 return (angletot > 4.0f) != ((::i32)nested % 2);
1284 return (angletot > 4.0f);
1322template <
typename RECT1,
typename RECT2 >
1323inline void expand_rect(RECT1& rectangle,
const RECT2& r)
1326 if (::is_null(rectangle))
1335 rectangle.left = minimum((
typename RECT1::UNIT_TYPE)rectangle.left, (
typename RECT1::UNIT_TYPE)r.left);
1336 rectangle.right = maximum((
typename RECT1::UNIT_TYPE)rectangle.right, (
typename RECT1::UNIT_TYPE)r.right);
1337 rectangle.top = minimum((
typename RECT1::UNIT_TYPE)rectangle.top, (
typename RECT1::UNIT_TYPE)r.top);
1338 rectangle.bottom = maximum((
typename RECT1::UNIT_TYPE)rectangle.bottom, (
typename RECT1::UNIT_TYPE)r.bottom);
1345template <
typename RECT1,
typename RECT2 >
1346inline void collapse_rect(RECT1& rectangle,
const RECT2& r)
1349 if (::is_null(rectangle))
1358 rectangle.left = maximum((
typename RECT1::UNIT_TYPE)rectangle.left, (
typename RECT1::UNIT_TYPE)r.left);
1359 rectangle.right = minimum((
typename RECT1::UNIT_TYPE)rectangle.right, (
typename RECT1::UNIT_TYPE)r.right);
1360 rectangle.top = maximum((
typename RECT1::UNIT_TYPE)rectangle.top, (
typename RECT1::UNIT_TYPE)r.top);
1361 rectangle.bottom = minimum((
typename RECT1::UNIT_TYPE)rectangle.bottom, (
typename RECT1::UNIT_TYPE)r.bottom);
1363 if (::width(rectangle) == 0 || height(rectangle) == 0)
1375template < prototype_po
int POINT >
1376inline constexpr auto __horz(
const POINT& point) {
return point.x; }
1377template < prototype_po
int POINT >
1378inline constexpr auto __vert(
const POINT& point) {
return point.y; }
1379template < prototype_size SIZE >
1380inline constexpr auto __horz(
const SIZE& size) {
return size.cx; }
1381template < prototype_size SIZE >
1382inline constexpr auto __vert(
const SIZE& size) {
return size.cy; }
1385template < prototype_rectangle RECTANGLE >
1386inline auto & top_left(
const RECTANGLE & rectangle) {
return *(
typename RECTANGLE::POINT_TYPE*)&rectangle; }
1387template < prototype_rectangle RECTANGLE >
1388inline auto & bottom_right(
const RECTANGLE& rectangle) {
return *(
typename RECTANGLE::POINT_TYPE*)&rectangle.right; }
1532 template < prototype_rectangle RECTANGLE >
1533 inline void deflate(RECTANGLE& rectangle, ::f64 dLeftRate, ::f64 dRightRate, ::f64 dTopRate, ::f64 dBottomRate)
1536 rectangle.left = range_rate(rectangle.left, rectangle.right, dLeftRate);
1538 rectangle.right = range_rate(rectangle.right, rectangle.left, dRightRate);
1540 rectangle.top = range_rate(rectangle.top, rectangle.bottom, dTopRate);
1542 rectangle.bottom = range_rate(rectangle.bottom, rectangle.top, dBottomRate);
Definition _initial_concepts.h:38