From c65bb2d972b24be1a113f6beca8ad73edb716652 Mon Sep 17 00:00:00 2001 From: Igor2 Date: Sat, 21 Nov 2015 20:05:36 +0100 Subject: [PATCH 3/5] circle-touches-box calculation with distance to avoid overflow. Signed-off-by: bert --- src/misc.c | 11 +++++++++++ src/misc.h | 1 + src/search.h | 6 +++--- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/misc.c b/src/misc.c index 48f5ed7..037da5e 100644 --- a/src/misc.c +++ b/src/misc.c @@ -110,6 +110,17 @@ Distance (double x1, double y1, double x2, double y2) return sqrt(delta_x * delta_x + delta_y * delta_y); } +/* Distance2() should be used so that there is only one + * place to deal with overflow/precision errors + */ +double +Distance2 (double x1, double y1, double x2, double y2) +{ + double delta_x = (x2 - x1); + double delta_y = (y2 - y1); + return delta_x * delta_x + delta_y * delta_y; +} + /* Bring an angle into [0, 360) range */ Angle NormalizeAngle (Angle a) diff --git a/src/misc.h b/src/misc.h index fdd7162..8070c24 100644 --- a/src/misc.h +++ b/src/misc.h @@ -43,6 +43,7 @@ typedef struct { } UnitList[]; double Distance (double x1, double y1, double x2, double y2); +double Distance2 (double x1, double y1, double x2, double y2); /* distance square */ Angle NormalizeAngle (Angle a); void r_delete_element (DataType *, ElementType *); diff --git a/src/search.h b/src/search.h index cd36740..b780181 100644 --- a/src/search.h +++ b/src/search.h @@ -71,14 +71,14 @@ int lines_intersect(Coord ax1, Coord ay1, Coord ax2, Coord ay2, Coord bx1, Coord /* == the same but accept if any part of the object touches the box == */ #define POINT_IN_CIRCLE(x, y, cx, cy, r) \ - (((x)-(cx)) * ((x)-(cx)) + ((y)-(cy)) * ((y)-(cy)) <= (r)*(r)) + (Distance2(x, y, cx, cy) <= (double)(r) * (double)(r)) -#define CIRCLE_TOUCH_BOX(cx, cy, r, b) \ +#define CIRCLE_TOUCHES_BOX(cx, cy, r, b) \ ( POINT_IN_BOX((cx)-(r),(cy),(b)) || POINT_IN_BOX((cx)+(r),(cy),(b)) || POINT_IN_BOX((cx),(cy)-(r),(b)) || POINT_IN_BOX((cx),(cy)+(r),(b)) \ || POINT_IN_CIRCLE((b)->X1, (b)->Y1, (cx), (cy), (r)) || POINT_IN_CIRCLE((b)->X2, (b)->Y1, (cx), (cy), (r)) || POINT_IN_CIRCLE((b)->X1, (b)->Y2, (cx), (cy), (r)) || POINT_IN_CIRCLE((b)->X2, (b)->Y2, (cx), (cy), (r))) #define VIA_OR_PIN_TOUCHES_BOX(v,b) \ - CIRCLE_TOUCH_BOX((v)->X,(v)->Y,((v)->Thickness + (v)->DrillingHole/2),(b)) + CIRCLE_TOUCHES_BOX((v)->X,(v)->Y,((v)->Thickness + (v)->DrillingHole/2),(b)) #define LINE_TOUCHES_BOX(l,b) \ ( lines_intersect((l)->Point1.X,(l)->Point1.Y,(l)->Point2.X,(l)->Point2.Y, (b)->X1, (b)->Y1, (b)->X2, (b)->Y1) \ -- 1.7.3.4