← Back to team overview

kicad-developers team mailing list archive

Re: PCBNEW NANOMETRES build zoom crash

 

On 04/18/2012 02:48 PM, jean-pierre charras wrote:
> Le 18/04/2012 20:25, Dick Hollenbeck a écrit :
>>> I am working on this today.
>>>
>>> My gut says this:
>>>
>>>
>>> Basically it comes down to the fact that we cannot describe an area larger than about 12
>>> feet with the nanometer internal units.
>>
>> Jean-Pierre,
>>
>> Can you first look over the attached patch, then play with it.
>>
>> This basically fixes the crash, but I think there's more finishing touches that need to be
>> done.
>>
>> I need to get back to work now.
>>
>>
>> Thank you very much,
>>
>> Dick
> I'll work on that tomorrow.
>
> I also make some tests.
> Under Windows I did now have crashes, but I had other issues.
>
> my opinion is with 32 bits integers we cannot handle more than something like 50 to 70 cm,
> with nanometers units.
>
> I noticed there are a lot of issues when calculating distance between 2 points.
>
> Assuming calculations are using integers, with 32 bits we can handle 2 meters distances only.
> if Xmax and Ymax are Y and Y difference between 2 points,
> only Y or Y max <= 1.4 meter, if sqrt( Xmax*Xmax + Ymax*Ymax) always < 2m.
>
> Because a distance is always >= 0, this means X and Y coordinates must have absolute coordinates < 70 cm.
> With margins around work area, and because Pcbnew and Gerbview use a page only with positive coordinates,
> the active area has a size < 50cm, roughly 20 inches, or A3 or B page size.


We should do the calculation in double, and return the result as a double.  The caller can
then use that result any way it chooses, say storing it in something other than
int, say double or long.  There really is no hurry to scamper back into "int" until you
actually have to store a coordinate in an object that you wish to retain.


Otherwise working in doubles should be more common, should be the norm, delaying the
conversion to "int" until the last possible moment.


I thought there was a conceptual bug in the function Distance() this morning, and wrote a
fix for it this morning.  The biggest problem was that IN THERE, in "double Distance()"
the result was being forced into an "int" then returned as a double.


See attached.


Good software design should allow us to work through these issues.  double Distance() is
only one example of where unnecessary design steps were taken before.


Dick



=== modified file 'polygon/math_for_graphics.cpp'
--- polygon/math_for_graphics.cpp	2012-04-17 14:18:14 +0000
+++ polygon/math_for_graphics.cpp	2012-04-18 14:55:55 +0000
@@ -12,6 +12,14 @@
 
 #define NM_PER_MIL 25400
 
+double Distance( double x1, double y1, double x2, double y2 )
+{
+    double dx = x1 - x2;
+    double dy = y1 - y2;
+    double d  = sqrt( dx * dx + dy * dy );
+    return d;
+}
+
 
 /**
  * Function TestLineHit
@@ -1031,7 +1039,7 @@
                     y2 = el2.Center.Y + el2.yrad*   sin( s2 );
                 }
 
-                double d = Distance( (int) x, (int) y, (int) x2, (int) y2 );
+                double d = Distance( x, y, x2, y2 );
 
                 if( d < dmin )
                 {
@@ -1101,7 +1109,7 @@
     }
 
     // find distance
-    return Distance( x, y, (int) xp, (int) yp );
+    return Distance( x, y, xp, yp );
 }
 
 
@@ -1151,7 +1159,7 @@
 
         // find distance
         if( InRange( xp, xi, xf ) && InRange( yp, yi, yf ) )
-            return Distance( x, y, (int) xp, (int) yp );
+            return Distance( x, y, xp, yp );
         else
             return min( Distance( x, y, xi, yi ), Distance( x, y, xf, yf ) );
     }
@@ -1177,26 +1185,6 @@
 }
 
 
-// Get distance between 2 points
-//
-double Distance( int x1, int y1, int x2, int y2 )
-{
-    double dx = x1 - x2;
-    double dy = y1 - y2;
-
-    double d  = sqrt( dx * dx + dy * dy );
-
-    if( d > INT_MAX || d < INT_MIN )
-    {
-        wxASSERT( 0 );
-    }
-
-    // wxASSERT( d <= INT_MAX && d >= INT_MIN );
-
-    return int( d );
-}
-
-
 // this finds approximate solutions
 // note: this works best if el2 is smaller than el1
 //
@@ -1368,7 +1356,7 @@
 
                 double  x2 = el2->Center.X + el2->xrad * cos( theta2 );
                 double  y2 = el2->Center.Y + el2->yrad * sin( theta2 );
-                double  d = Distance( (int) x, (int) y, (int) x2, (int) y2 );
+                double  d = Distance( x,  y, x2, y2 );
 
                 if( d < dmin )
                 {


Follow ups

References