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

Re: gEDA-user: DRC problem at close pads



Dan McMahill wrote:
David Kuehling wrote:

"DJ" == DJ Delorie <dj@xxxxxxxxxxx> writes:



http://user.cs.tu-berlin.de/~dvdkhlng/clearance-problem.png



Could you post (or send me privately) the .pcb file?



Here is a simplified file that only contains the problematic footprint. Quite possibly this is just a problem with the footprint? After all this was hand-coded in M4...


I'd be more likely to suspect the footprint if "after all it was hand drawn instead of generated programattically"...

Ok, here's the deal. It is a bug in pcb. Square (or rectangular) pads are checked by growing one of them in X and Y on all 4 sides by the minimum space. This of course means that the corners grew by sqrt(2) more and thats why you got a failures. I'll try to cook up a patch tonight.

could you try out the attached patch? I'd appreciate it if you tried it out on some corner cases where the spacing should just barely pass or just barely fail both on pads on a single row and on those corners.


I think it seems ok, but until there is some sort of regression testsuite in place I'm nervious about that part of the code....

-Dan


Index: src/find.c
===================================================================
RCS file: /cvsroot/pcb/pcb/src/find.c,v
retrieving revision 1.59
diff -u -2 -r1.59 find.c
--- src/find.c	5 Nov 2006 01:27:13 -0000	1.59
+++ src/find.c	27 Feb 2007 01:41:06 -0000
@@ -432,4 +432,15 @@
       BoxType b1, b2;
 
+      /* Here we are trying to find out if two rectangles have at least
+       * Bloat space between them.  Note that this takes more care than
+       * simply blowing out one of the rectangles by Bloat on all sides.
+       * That only works if the shortest line between the two original
+       * rectangles is perpendicular to the sids of the rectangles.
+       *
+       */
+
+      /* Step #1 find out if the shortest line is perpendicular to 
+       * the closest edge
+       */
       b1.X1 = MIN (p1->Point1.X, p1->Point2.X) - (p1->Thickness + 1) / 2;
       b1.Y1 = MIN (p1->Point1.Y, p1->Point2.Y) - (p1->Thickness + 1) / 2;
@@ -437,17 +448,64 @@
       b1.Y2 = MAX (p1->Point1.Y, p1->Point2.Y) + (p1->Thickness + 1) / 2;
 
-      b2.X1 =
-        MIN (p2->Point1.X,
-             p2->Point2.X) - MAX ((p2->Thickness + 1) / 2 + Bloat, 0);
-      b2.Y1 =
-        MIN (p2->Point1.Y,
-             p2->Point2.Y) - MAX ((p2->Thickness + 1) / 2 + Bloat, 0);
-      b2.X2 =
-        MAX (p2->Point1.X,
-             p2->Point2.X) + MAX ((p2->Thickness + 1) / 2 + Bloat, 0);
-      b2.Y2 =
-        MAX (p2->Point1.Y,
-             p2->Point2.Y) + MAX ((p2->Thickness + 1) / 2 + Bloat, 0);
-      return BoxBoxIntersection (&b1, &b2);
+      b2.X1 = MIN (p2->Point1.X, p2->Point2.X) - (p2->Thickness + 1) / 2;
+      b2.Y1 = MIN (p2->Point1.Y, p2->Point2.Y) - (p2->Thickness + 1) / 2;
+      b2.X2 = MAX (p2->Point1.X, p2->Point2.X) + (p2->Thickness + 1) / 2;
+      b2.Y2 = MAX (p2->Point1.Y, p2->Point2.Y) + (p2->Thickness + 1) / 2;
+
+      if ( (b2.X1 <= b1.X2 && b2.X2 >= b1.X1) ||
+	   (b2.Y1 <= b1.Y2 && b2.Y2 >= b1.Y1) )
+	{
+	  b2.X1 =
+	    MIN (p2->Point1.X,
+		 p2->Point2.X) - MAX ((p2->Thickness + 1) / 2 + Bloat, 0);
+	  b2.Y1 =
+	    MIN (p2->Point1.Y,
+		 p2->Point2.Y) - MAX ((p2->Thickness + 1) / 2 + Bloat, 0);
+	  b2.X2 =
+	    MAX (p2->Point1.X,
+		 p2->Point2.X) + MAX ((p2->Thickness + 1) / 2 + Bloat, 0);
+	  b2.Y2 =
+	    MAX (p2->Point1.Y,
+		 p2->Point2.Y) + MAX ((p2->Thickness + 1) / 2 + Bloat, 0);
+	  return BoxBoxIntersection (&b1, &b2);
+	}
+      else
+	{
+	  /* the shortest line is between two corners */
+	  double x1, x2, y1, y2, d;
+	  
+	  if (b2.X2 < b1.X1)
+	    {
+	      /* b2 is to the left of b1 */
+	      x1 = (double) b1.X1;
+	      x2 = (double) b2.X2;
+	    }
+	  else
+	    {
+	      /* b2 is to the right of b1 */
+	      x1 = (double) b1.X2;
+	      x2 = (double) b2.X1;
+	    }
+
+	  if (b2.Y2 < b1.Y1)
+	    {
+	      /* b2 is above b1 */
+	      y1 = (double) b1.Y1;
+	      y2 = (double) b2.Y2;
+	    }
+	  else
+	    {
+	      /* b2 is below b1 */
+	      y1 = (double) b1.Y2;
+	      y2 = (double) b2.Y1;
+	    }
+
+	  /* use floating point math to avoid overflows here */
+	  if ( (x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2) < ((double) Bloat)*((double) Bloat) )
+	    return TRUE;
+	  else
+	    return FALSE;
+	}
+      
     }
   if (TEST_FLAG (SQUAREFLAG, p1))
@@ -455,5 +513,5 @@
   return LinePadIntersect ((LineTypePtr) p1, p2);
 }
-
+      
 static inline Boolean
 PV_TOUCH_PV (PinTypePtr PV1, PinTypePtr PV2)

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