[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

gEDA-cvs: pcb.git: branch: master updated (79417191949173c16579554dc8f8d5b9cbb22b3a)



The branch, master has been updated
       via  79417191949173c16579554dc8f8d5b9cbb22b3a (commit)
      from  93dbc950600032062d26ffa73c99c5f634a0478c (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


=========
 Summary
=========

 src/main.c    |    2 ++
 src/misc.c    |   24 ++++++++++++++++++------
 src/polygon.c |   40 ++++++++++++++++++----------------------
 src/polygon.h |   17 +++++++++++++++++
 src/thermal.c |   14 ++++++++++----
 5 files changed, 65 insertions(+), 32 deletions(-)


=================
 Commit Messages
=================

commit 79417191949173c16579554dc8f8d5b9cbb22b3a
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Fix geometry errors caused by commit 2d8dc8a3a3a55158b4e6278dd9f40588e4111c2d
    
    This fixes up problems from the following commit:
    
        [PATCH] fix bug 2793480 (vias/arcs-to-polygon clearances)
    
        frac_circle(): introduce radius_adjustment factor to make
        the polygon outline the arc rather than connet points on the arc
    
        ArcPolyNoIntersect(): compute number of segments so that
        polygon diverges from the arc no more than 0.02 of
        required thickness; adjust outer "arc" radius like in frac_circle()
    
    The object bounding boxes for arcs, vias, lines and rounded pads which
    determine the maximum area affected by that object were no longer
    correct, leading to artaefacts when doing incremental polygon processing.
    
    It also lead to missing fragments in (the non-curved + and x type
    thermals). These are also fixed up by this patch.

:100644 100644 581c7cb... d14c935... M	src/main.c
:100644 100644 649208c... 02a883f... M	src/misc.c
:100644 100644 78cc3b2... 37e0528... M	src/polygon.c
:100644 100644 e29f67f... 315e69b... M	src/polygon.h
:100644 100644 f9dd369... d1df1fc... M	src/thermal.c

=========
 Changes
=========

commit 79417191949173c16579554dc8f8d5b9cbb22b3a
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Fix geometry errors caused by commit 2d8dc8a3a3a55158b4e6278dd9f40588e4111c2d
    
    This fixes up problems from the following commit:
    
        [PATCH] fix bug 2793480 (vias/arcs-to-polygon clearances)
    
        frac_circle(): introduce radius_adjustment factor to make
        the polygon outline the arc rather than connet points on the arc
    
        ArcPolyNoIntersect(): compute number of segments so that
        polygon diverges from the arc no more than 0.02 of
        required thickness; adjust outer "arc" radius like in frac_circle()
    
    The object bounding boxes for arcs, vias, lines and rounded pads which
    determine the maximum area affected by that object were no longer
    correct, leading to artaefacts when doing incremental polygon processing.
    
    It also lead to missing fragments in (the non-curved + and x type
    thermals). These are also fixed up by this patch.

diff --git a/src/main.c b/src/main.c
index 581c7cb..d14c935 100644
--- a/src/main.c
+++ b/src/main.c
@@ -55,6 +55,7 @@
 #include "misc.h"
 #include "lrealpath.h"
 #include "free_atexit.h"
+#include "polygon.h"
 
 #include "hid/common/actions.h"
 
@@ -909,6 +910,7 @@ main (int argc, char *argv[])
 
   srand ( time(NULL) ); /* Set seed for rand() */
 
+  polygon_init ();
   hid_init ();
 
   hid_load_settings ();
diff --git a/src/misc.c b/src/misc.c
index 649208c..02a883f 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -173,6 +173,10 @@ SetPinBoundingBox (PinTypePtr Pin)
    */
   width = (Pin->Clearance + Pin->Thickness + 1) / 2;
   width = MAX (width, (Pin->Mask + 1) / 2);
+
+  /* Adjust for our discrete polygon approximation */
+  width = (int)((float)width * POLY_CIRC_RADIUS_ADJ + 0.5);
+
   Pin->BoundingBox.X1 = Pin->X - width;
   Pin->BoundingBox.Y1 = Pin->Y - width;
   Pin->BoundingBox.X2 = Pin->X + width;
@@ -226,6 +230,9 @@ SetPadBoundingBox (PadTypePtr Pad)
     }
   else
     {
+      /* Adjust for our discrete polygon approximation */
+      width = (int)((float)width * POLY_CIRC_RADIUS_ADJ + 0.5);
+
       Pad->BoundingBox.X1 = MIN (Pad->Point1.X, Pad->Point2.X) - width;
       Pad->BoundingBox.X2 = MAX (Pad->Point1.X, Pad->Point2.X) + width;
       Pad->BoundingBox.Y1 = MIN (Pad->Point1.Y, Pad->Point2.Y) - width;
@@ -244,6 +251,9 @@ SetLineBoundingBox (LineTypePtr Line)
 
   width = (Line->Thickness + Line->Clearance + 1) / 2;
 
+  /* Adjust for our discrete polygon approximation */
+  width = (int)((float)width * POLY_CIRC_RADIUS_ADJ + 0.5);
+
   Line->BoundingBox.X1 = MIN (Line->Point1.X, Line->Point2.X) - width;
   Line->BoundingBox.X2 = MAX (Line->Point1.X, Line->Point2.X) + width;
   Line->BoundingBox.Y1 = MIN (Line->Point1.Y, Line->Point2.Y) - width;
@@ -1333,10 +1343,10 @@ GetObjectBoundingBox (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
 void
 SetArcBoundingBox (ArcTypePtr Arc)
 {
-  register double ca1, ca2, sa1, sa2;
+  double ca1, ca2, sa1, sa2;
   double minx, maxx, miny, maxy;
-  register LocationType ang1, ang2, delta, a;
-  register LocationType width;
+  LocationType ang1, ang2, delta, a;
+  LocationType width;
 
   /* first put angles into standard form */
   if (Arc->Delta > 360)
@@ -1398,14 +1408,16 @@ SetArcBoundingBox (ArcTypePtr Arc)
     }
 
   Arc->BoundingBox.X2 = Arc->X - Arc->Width * minx;
-
   Arc->BoundingBox.X1 = Arc->X - Arc->Width * maxx;
-
   Arc->BoundingBox.Y2 = Arc->Y + Arc->Height * maxy;
-
   Arc->BoundingBox.Y1 = Arc->Y + Arc->Height * miny;
 
   width = (Arc->Thickness + Arc->Clearance) / 2;
+
+  /* Adjust for our discrete polygon approximation */
+  width = (int)((float)width * MAX (POLY_CIRC_RADIUS_ADJ,
+                                     (1.0 + POLY_ARC_MAX_DEVIATION)) + 0.5);
+
   Arc->BoundingBox.X1 -= width;
   Arc->BoundingBox.X2 += width;
   Arc->BoundingBox.Y1 -= width;
diff --git a/src/polygon.c b/src/polygon.c
index 78cc3b2..37e0528 100644
--- a/src/polygon.c
+++ b/src/polygon.c
@@ -108,20 +108,17 @@ dicer output is used for HIDs which cannot render things with holes
 #define SUBTRACT_PIN_VIA_BATCH_SIZE 100
 #define SUBTRACT_LINE_BATCH_SIZE 20
 
-/* ---------------------------------------------------------------------------
- * local prototypes
- */
+static double rotate_circle_seg[4];
 
-#define CIRC_SEGS 40
-static double circleVerticies[] = {
-  1.0, 0.0,
-  0.98768834059513777, 0.15643446504023087,
-};
-/* adjustment to make the segments
- * outline the circle rather than connect
- * points on the circle
- * 1 - cos(\alpha/2) < (\alpha/2)^2/2 */
-static double radius_adjustment = (M_PI/CIRC_SEGS)*(M_PI/CIRC_SEGS)/2;
+void
+polygon_init (void)
+{
+  double cos_ang = cos (2.0 * M_PI / POLY_CIRC_SEGS_F);
+  double sin_ang = sin (2.0 * M_PI / POLY_CIRC_SEGS_F);
+
+  rotate_circle_seg[0] = cos_ang;  rotate_circle_seg[1] = -sin_ang;
+  rotate_circle_seg[2] = sin_ang;  rotate_circle_seg[3] =  cos_ang;
+}
 
 Cardinal
 polygon_point_idx (PolygonTypePtr polygon, PointTypePtr point)
@@ -401,16 +398,16 @@ frac_circle (PLINE * c, LocationType X, LocationType Y, Vector v, int range)
 
   poly_InclVertex (c->head.prev, poly_CreateNode (v));
   /* move vector to origin */
-  e1 = (v[0] - X) * (1 + radius_adjustment);
-  e2 = (v[1] - Y) * (1 + radius_adjustment);
+  e1 = (v[0] - X) * POLY_CIRC_RADIUS_ADJ;
+  e2 = (v[1] - Y) * POLY_CIRC_RADIUS_ADJ;
 
   /* NB: the caller adds the last vertex, hence the -1 */
-  range = CIRC_SEGS / range - 1;
+  range = POLY_CIRC_SEGS / range - 1;
   for (i = 0; i < range; i++)
     {
       /* rotate the vector */
-      t1 = e1 * circleVerticies[2] - e2 * circleVerticies[3];
-      e2 = e1 * circleVerticies[3] + e2 * circleVerticies[2];
+      t1 = rotate_circle_seg[0] * e1 + rotate_circle_seg[1] * e2;
+      e2 = rotate_circle_seg[2] * e1 + rotate_circle_seg[3] * e2;
       e1 = t1;
       v[0] = X + ROUND (e1);
       v[1] = Y + ROUND (e2);
@@ -480,8 +477,6 @@ ArcPolyNoIntersect (ArcType * a, BDimension thick)
   int i, segs;
   double ang, da, rx, ry;
   long half;
-  static const double delta_th = 0.02; /* polygon diverges from modelled arc
-					  no more than delta_th * thick */
   double radius_adj;
 
   if (thick <= 0)
@@ -498,8 +493,9 @@ ArcPolyNoIntersect (ArcType * a, BDimension thick)
   ry = MAX (a->Height - half, 0);
   segs = 1;
   if(thick > 0)
-    segs = MAX (segs, a->Delta * M_PI / 360
-		* sqrt(sqrt((double)rx*rx + (double)ry*ry)/delta_th/2/thick));
+    segs = MAX (segs, a->Delta * M_PI / 360 *
+                      sqrt (sqrt ((double)rx * rx + (double)ry * ry) /
+                            POLY_ARC_MAX_DEVIATION / 2 / thick));
   segs = MAX(segs, a->Delta / ARC_ANGLE);
 
   ang = a->StartAngle;
diff --git a/src/polygon.h b/src/polygon.h
index e29f67f..315e69b 100644
--- a/src/polygon.h
+++ b/src/polygon.h
@@ -33,6 +33,23 @@
 
 #include "global.h"
 
+/* Implementation constants */
+
+#define POLY_CIRC_SEGS 40
+#define POLY_CIRC_SEGS_F ((float)POLY_CIRC_SEGS)
+
+/* adjustment to make the segments outline the circle rather than connect
+ * points on the circle: 1 - cos (\alpha / 2) < (\alpha / 2) ^ 2 / 2
+ */
+#define POLY_CIRC_RADIUS_ADJ (1.0 + M_PI / POLY_CIRC_SEGS_F * \
+                                    M_PI / POLY_CIRC_SEGS_F / 2.0)
+
+/* polygon diverges from modelled arc no more than MAX_ARC_DEVIATION * thick */
+#define POLY_ARC_MAX_DEVIATION 0.02
+
+/* Prototypes */
+
+void polygon_init (void);
 Cardinal polygon_point_idx (PolygonTypePtr polygon, PointTypePtr point);
 Cardinal polygon_point_contour (PolygonTypePtr polygon, Cardinal point);
 Cardinal prev_contour_point (PolygonTypePtr polygon, Cardinal point);
diff --git a/src/thermal.c b/src/thermal.c
index f9dd369..d1df1fc 100644
--- a/src/thermal.c
+++ b/src/thermal.c
@@ -436,15 +436,21 @@ ThermPoly (PCBTypePtr p, PinTypePtr pin, Cardinal laynum)
         /* fix me needs error checking */
         if (style == 2)
           {
-            pa = RectPoly (pin->X - t, pin->X + t, pin->Y - w, pin->Y + w);
+            /* t is the theoretically required length, but we use twice that
+             * to avoid descritisation errors in our circle approximation.
+             */
+            pa = RectPoly (pin->X - t * 2, pin->X + t * 2, pin->Y - w, pin->Y + w);
             poly_Boolean_free (m, pa, &arc, PBO_SUB);
-            pa = RectPoly (pin->X - w, pin->X + w, pin->Y - t, pin->Y + t);
+            pa = RectPoly (pin->X - w, pin->X + w, pin->Y - t * 2, pin->Y + t * 2);
           }
         else
           {
-            pa = diag_line (pin->X, pin->Y, t, w, true);
+            /* t is the theoretically required length, but we use twice that
+             * to avoid descritisation errors in our circle approximation.
+             */
+            pa = diag_line (pin->X, pin->Y, t * 2, w, true);
             poly_Boolean_free (m, pa, &arc, PBO_SUB);
-            pa = diag_line (pin->X, pin->Y, t, w, false);
+            pa = diag_line (pin->X, pin->Y, t * 2, w, false);
           }
         poly_Boolean_free (arc, pa, &m, PBO_SUB);
         return m;




_______________________________________________
geda-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs