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

Re: gEDA-user: Embedded polygon



On Tue, 2011-01-18 at 21:19 +0100, Martin Kupec wrote:
> > 4. Longer term - do we need to revisit the maths used to create thermal
> > shapes? How do we fix this without risking breaking old designs?
> IMHO there is a glitch in calculating some arcs. And also there is a
> problem with calculating intersections, but it seems to be fixed in the
> OpenGL branch.

Here is the crux of the problem for me.

Up until we merged Harry Eaton's clipper branch, thermals were simple
little things like "+" or "X", with square edged fingers.

commit 38f21ae8ac1d1fc673f579f52aa2d5febfa6f9d9
Date:   Mon Oct 9 00:35:24 2006 +0000

The finger width was related to the width of the copper annulus by a
factor specified in the file's "Thermal[0.5]" directive.

That default of 0.5, sets the width of the thermal finger equal to the
copper annulus.


After the clipper branch, thermal finger width related only to the
clearance of the pin. For many cases, this causes a problem. In
addition, the rounded thermal styles appear to have computed the finger
width incorrectly.

Aside from this, there are still some problems - the ArcPoly function
doesn't appear to do very well for geometries where the hemispherical
caps around the end of the arc intersect with each other.

Also, for some geometries, the thermal "cutout" (for want of a better
word) ceases to be an arc wrapping around the pin or via, but should
become some radially extending shape.


Perhaps both approaches are wrong. What is the _correct_ (if there is
such a thing) calculation to determine a thermal shape for a given pin
or via?

I've attached my work in progress.

-- 
Peter Clifton

Electrical Engineering Division,
Engineering Department,
University of Cambridge,
9, JJ Thomson Avenue,
Cambridge
CB3 0FA

Tel: +44 (0)7729 980173 - (No signal in the lab!)
Tel: +44 (0)1223 748328 - (Shared lab phone, ask for me)
From 9e7859fcb7e607602f6d015dd2333ab5ac362191 Mon Sep 17 00:00:00 2001
From: Peter Clifton <pcjc2@xxxxxxxxx>
Date: Tue, 18 Jan 2011 20:35:08 +0000
Subject: [PATCH] Fix thermal generation

---
 src/change.c  |   17 ++++++++---------
 src/thermal.c |   38 ++++++++++++++++++++++++++++++--------
 2 files changed, 38 insertions(+), 17 deletions(-)

diff --git a/src/change.c b/src/change.c
index 9a2e80b..8e6ea63 100644
--- a/src/change.c
+++ b/src/change.c
@@ -440,21 +440,20 @@ ChangeVia2ndSize (PinTypePtr Via)
     {
       AddObjectTo2ndSizeUndoList (VIA_TYPE, Via, Via, Via);
       EraseVia (Via);
+      RestoreToPolygon (PCB->Data, VIA_TYPE, Via, Via);
       Via->DrillingHole = value;
       if (TEST_FLAG (HOLEFLAG, Via))
 	{
-	  RestoreToPolygon (PCB->Data, VIA_TYPE, Via, Via);
 	  AddObjectToSizeUndoList (VIA_TYPE, Via, Via, Via);
 	  Via->Thickness = value;
-	  ClearFromPolygon (PCB->Data, VIA_TYPE, Via, Via);
 	}
+      ClearFromPolygon (PCB->Data, VIA_TYPE, Via, Via);
       DrawVia (Via, 0);
       return (Via);
     }
   return (NULL);
 }
 
-
 /* ---------------------------------------------------------------------------
  * changes the clearance size of a via 
  * returns TRUE if changed
@@ -639,15 +638,15 @@ ChangeElement2ndSize (ElementTypePtr Element)
 	changed = true;
 	AddObjectTo2ndSizeUndoList (PIN_TYPE, Element, pin, pin);
 	ErasePin (pin);
+	RestoreToPolygon (PCB->Data, PIN_TYPE, Element, pin);
 	pin->DrillingHole = value;
-	DrawPin (pin, 0);
 	if (TEST_FLAG (HOLEFLAG, pin))
 	  {
-	    RestoreToPolygon (PCB->Data, PIN_TYPE, Element, pin);
 	    AddObjectToSizeUndoList (PIN_TYPE, Element, pin, pin);
 	    pin->Thickness = value;
-	    ClearFromPolygon (PCB->Data, PIN_TYPE, Element, pin);
 	  }
+	ClearFromPolygon (PCB->Data, PIN_TYPE, Element, pin);
+	DrawPin (pin, 0);
       }
   }
   END_LOOP;
@@ -676,15 +675,15 @@ ChangePin2ndSize (ElementTypePtr Element, PinTypePtr Pin)
     {
       AddObjectTo2ndSizeUndoList (PIN_TYPE, Element, Pin, Pin);
       ErasePin (Pin);
+      RestoreToPolygon (PCB->Data, PIN_TYPE, Element, Pin);
       Pin->DrillingHole = value;
-      DrawPin (Pin, 0);
       if (TEST_FLAG (HOLEFLAG, Pin))
 	{
-	  RestoreToPolygon (PCB->Data, PIN_TYPE, Element, Pin);
 	  AddObjectToSizeUndoList (PIN_TYPE, Element, Pin, Pin);
 	  Pin->Thickness = value;
-	  ClearFromPolygon (PCB->Data, PIN_TYPE, Element, Pin);
 	}
+      ClearFromPolygon (PCB->Data, PIN_TYPE, Element, Pin);
+      DrawPin (Pin, 0);
       return (Pin);
     }
   return (NULL);
diff --git a/src/thermal.c b/src/thermal.c
index f9dd369..93064f4 100644
--- a/src/thermal.c
+++ b/src/thermal.c
@@ -428,7 +428,7 @@ ThermPoly (PCBTypePtr p, PinTypePtr pin, Cardinal laynum)
       {
         POLYAREA *m;
         BDimension t = (pin->Thickness + pin->Clearance) / 2;
-        BDimension w = 0.5 * pcb->ThermScale * pin->Clearance;
+        BDimension w = pcb->ThermScale * (pin->Thickness - pin->DrillingHole);
         pa = CirclePoly (pin->X, pin->Y, t);
         arc = CirclePoly (pin->X, pin->Y, pin->Thickness / 2);
         /* create a thin ring */
@@ -436,15 +436,25 @@ 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);
+            pa = RectPoly (pin->X - t /* To avoid approximation errors: */ - w,
+                           pin->X + t /* To avoid approximation errors: */ + w,
+                           pin->Y - w / 2,
+                           pin->Y + w / 2);
             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 / 2,
+                           pin->X + w / 2,
+                           pin->Y - t /* To avoid approximation errors: */ - w,
+                           pin->Y + t /* To avoid approximation errors: */ + w);
           }
         else
           {
-            pa = diag_line (pin->X, pin->Y, t, w, true);
+            pa = diag_line (pin->X, pin->Y,
+                            t /* To avoid approximation errors: */ + w,
+                            w / 2, 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 /* To avoid approximation errors: */ + w,
+                            w / 2, false);
           }
         poly_Boolean_free (arc, pa, &m, PBO_SUB);
         return m;
@@ -458,9 +468,21 @@ ThermPoly (PCBTypePtr p, PinTypePtr pin, Cardinal laynum)
       a.Thickness = 1;
       a.Clearance = pin->Clearance / 2;
       a.Flags = NoFlags ();
-      a.Delta =
-        90 -
-        (a.Clearance * (1. + 2. * pcb->ThermScale) * 180) / (M_PI * a.Width);
+      a.Delta = 90 -
+        2 * asin (((pin->Thickness - pin->DrillingHole) * pcb->ThermScale / 2 +
+                   a.Clearance / 2) / a.Width) / M_PI * 180;
+      if (a.Delta < 0)
+        {
+          a.Delta = 0;
+          printf ("THERMAL DELTA < 0\n");
+          /* This is bad - we need a different shape entirely */
+        }
+      if (a.Delta < 10)
+        {
+          a.Delta = 10;
+          printf ("THERMAL DELTA < 10\n");
+          /* Quick kludge around broken ArcPoly implementation */
+        }
       a.StartAngle = 90 - a.Delta / 2 + (style == 4 ? 0 : 45);
       pa = ArcPoly (&a, a.Clearance);
       if (!pa)
-- 
1.7.1


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