I need a function that returns the distance between a point and the edge of
a smd pad. If the point is inside the pad, I'd want it to return 0.
Anyone tried doing that? I want the roundness of the smd to be a part of the
function too.
I need a function that returns the distance between a point and the edge of
a smd pad. If the point is inside the pad, I'd want it to return 0.
Anyone tried doing that? I want the roundness of the smd to be a part of the
function too.
I should post this bug warning. The position of the corner circles may be
wrong. They should probably be positioned at xs±edg/2,ys±edg/2 instead of
xs±edg,ys±edg.
"Morten Leikvoll" <mleikvol@yahoo.nospam> wrote in message
news:hh9qlp$6ok$1@cheetah.cadsoft.de...
"Morten Leikvoll" <mleikvol@yahoo.nospam> wrote in message
news:hga74q$qco$1@cheetah.cadsoft.de...
I need a function that returns the distance between a point and the edge
of a smd pad. If the point is inside the pad, I'd want it to return 0.
Anyone tried doing that? I want the roundness of the smd to be a part of
the function too.
If any interest, here is one way of doing it (with printf's for debugging
commented out).
It basicaly turns a SMD into an octacon and 4 corner circles, checks the
distance to each side + circles, then picks the smallest.
Of course I can not guarantee that it will work for all types of smds, but
it should work for the basic ones. It will not detect wether you are
inside the smd or not, just the smallest distance to the smd edge.
--------------
int Point2PointDistance(real x1, real y1, real x2, real y2)
{
return floor(sqrt( ((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2))));
}
int Point2WireDistance(int x, int y, int x1, int y1,int x2,int y2)
{
int Ux = x - x1;
int Uy = y - y1;
int Vx = x2 - x1;
int Vy = y2 - y1;
real dot = 1.0 * Ux * Vx + 1.0 * Uy * Vy;
real len_sq = 1.0 * Vx * Vx + 1.0 * Vy * Vy;
if(len_sq==0) return 0; //line len is 0
real param = dot / len_sq;
if(param<0) param=0;
if(param>1) param=1;
real xx = round(paramVx + 1.0x1);
real yy = round(paramVy + 1.0y1);
return Point2PointDistance(x,y,xx,yy);
}
int smddist(int x,int y,UL_CONTACT C)
{
int dist,t,t1;
int x1,y1,x2,y2;
int xs,ys,ang;
xs=round(C.smd.dx/2);
ys=round(C.smd.dy/2);
ang=C.smd.angle;
int edg=(xs<ys)?xs:ys;//smallest edge
edg=edg-round(1.0edgC.smd.roundness/100);//radius of corner circles
//printf("Checking point (%f %f) distance to smd at (%f
%f)\n",u2mm(x),u2mm(y),u2mm(C.x),u2mm(C.y));
x1=C.x+round(cos(PIang/180)(xs-edg)-sin(PIang/180)ys); //find dist to
upper wire
y1=C.yround(sin(PIang/180)(xs-edg)cos(PIang/180)ys);
x2=C.xround(cos(PIang/180)(-xsedg)-sin(PIang/180)ys);
y2=C.yround(sin(PIang/180)(-xsedg)+cos(PIang/180)ys);
t1=Point2WireDistance(x,y,x1,y1,x2,y2);
dist=t1;
//printf("\tDist to upper wire (%f %f) (%f
%f):%f\n",u2mm(x1),u2mm(y1),u2mm(x2),u2mm(y2),u2mm(t1));
x1=C.x+round(cos(PIang/180)(xs-edg)-sin(PIang/180)(-ys)); //find dist
to lower wire
y1=C.yround(sin(PIang/180)(xs-edg)cos(PIang/180)(-ys));
x2=C.xround(cos(PIang/180)(-xsedg)-sin(PIang/180)(-ys));
y2=C.yround(sin(PIang/180)(-xsedg)+cos(PIang/180)(-ys));
t1=Point2WireDistance(x,y,x1,y1,x2,y2);
if(t1<dist) dist=t1;
//printf("\tDist to lower wire (%f %f) (%f
%f):%f\n",u2mm(x1),u2mm(y1),u2mm(x2),u2mm(y2),u2mm(t1));
x1=C.x+round(cos(PIang/180)(-xs)-sin(PIang/180)(ys-edg)); //find dist
to left wire
y1=C.yround(sin(PIang/180)(-xs)cos(PIang/180)(ys-edg));
x2=C.xround(cos(PIang/180)(-xs)-sin(PIang/180)(-ysedg));
y2=C.yround(sin(PIang/180)(-xs)cos(PIang/180)(-ys+edg));
t1=Point2WireDistance(x,y,x1,y1,x2,y2);
if(t1<dist) dist=t1;
//printf("\tDist to left wire (%f %f) (%f
%f):%f\n",u2mm(x1),u2mm(y1),u2mm(x2),u2mm(y2),u2mm(t1));
x1=C.x+round(cos(PIang/180)(xs)-sin(PIang/180)(ys-edg)); //find dist
to right wire
y1=C.yround(sin(PIang/180)(xs)cos(PIang/180)(ys-edg));
x2=C.xround(cos(PIang/180)(xs)-sin(PIang/180)(-ysedg));
y2=C.yround(sin(PIang/180)(xs)cos(PIang/180)(-ys+edg));
t1=Point2WireDistance(x,y,x1,y1,x2,y2);
if(t1<dist) dist=t1;
//printf("\tDist to right wire (%f %f) (%f
%f):%f\n",u2mm(x1),u2mm(y1),u2mm(x2),u2mm(y2),u2mm(t1));
if(edg)
{
x1=C.x+round(cos(PIang/180)(xs-edg)-sin(PIang/180)(ys-edg)); //circle
in upper right corner
y1=C.yround(sin(PIang/180)(xs-edg)cos(PIang/180)(ys-edg));
t=Point2PointDistance(x,y,x1,y1)-edg; // check dist to circle in upper
right corner
//printf("\tDist to upper right corner circle(%f
%f):%f\n",u2mm(x1),u2mm(y1),u2mm(t));
if(t<dist) dist=t;
x1=C.xround(cos(PIang/180)(xs-edg)-sin(PIang/180)(-ysedg));
//circle in lower right corner
y1=C.yround(sin(PIang/180)(xs-edg)cos(PIang/180)(-ys+edg));
t=Point2PointDistance(x,y,x1,y1)-edg; // check dist to circle in lower
right corner
//printf("\tDist to lower right corner circle(%f
%f):%f\n",u2mm(x1),u2mm(y1),u2mm(t));
if(t<dist) dist=t;
x1=C.xround(cos(PIang/180)(-xsedg)-sin(PIang/180)(-ys+edg));
//circle in lower left corner
y1=C.yround(sin(PIang/180)(-xsedg)cos(PIang/180)(-ysedg));
t=Point2PointDistance(x,y,x1,y1)-edg; // check dist to circle in lower
left corner
//printf("\tDist to lower left corner circle(%f
%f):%f\n",u2mm(x1),u2mm(y1),u2mm(t));
if(t<dist) dist=t;
x1=C.xround(cos(PIang/180)(-xsedg)-sin(PIang/180)(ys-edg));
//circle in upper left corner
y1=C.yround(sin(PIang/180)(-xsedg)+cos(PIang/180)(ys-edg));
t=Point2PointDistance(x,y,x1,y1)-edg; // check dist to circle in upper
left corner
//printf("\tDist to upper left corner circle(%f
%f):%f\n",u2mm(x1),u2mm(y1),u2mm(t));
if(t<dist) dist=t;
}
//printf("\tDistance=%f\n",u2mm(dist));
return dist;
}
I should post this bug warning. The position of the corner circles may be
wrong. They should probably be positioned at xs±edg/2,ys±edg/2 instead of
xs±edg,ys±edg.
"Morten Leikvoll" <mleikvol@yahoo.nospam> wrote in message
news:hh9qlp$6ok$1@cheetah.cadsoft.de...
"Morten Leikvoll" <mleikvol@yahoo.nospam> wrote in message
news:hga74q$qco$1@cheetah.cadsoft.de...
I need a function that returns the distance between a point and the edge
of a smd pad. If the point is inside the pad, I'd want it to return 0.
Anyone tried doing that? I want the roundness of the smd to be a part of
the function too.
If any interest, here is one way of doing it (with printf's for debugging
commented out).
It basicaly turns a SMD into an octacon and 4 corner circles, checks the
distance to each side + circles, then picks the smallest.
Of course I can not guarantee that it will work for all types of smds, but
it should work for the basic ones. It will not detect wether you are
inside the smd or not, just the smallest distance to the smd edge.
--------------
int Point2PointDistance(real x1, real y1, real x2, real y2)
{
return floor(sqrt( ((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2))));
}
int Point2WireDistance(int x, int y, int x1, int y1,int x2,int y2)
{
int Ux = x - x1;
int Uy = y - y1;
int Vx = x2 - x1;
int Vy = y2 - y1;
real dot = 1.0 * Ux * Vx + 1.0 * Uy * Vy;
real len_sq = 1.0 * Vx * Vx + 1.0 * Vy * Vy;
if(len_sq==0) return 0; //line len is 0
real param = dot / len_sq;
if(param<0) param=0;
if(param>1) param=1;
real xx = round(paramVx + 1.0x1);
real yy = round(paramVy + 1.0y1);
return Point2PointDistance(x,y,xx,yy);
}
int smddist(int x,int y,UL_CONTACT C)
{
int dist,t,t1;
int x1,y1,x2,y2;
int xs,ys,ang;
xs=round(C.smd.dx/2);
ys=round(C.smd.dy/2);
ang=C.smd.angle;
int edg=(xs<ys)?xs:ys;//smallest edge
edg=edg-round(1.0edgC.smd.roundness/100);//radius of corner circles
//printf("Checking point (%f %f) distance to smd at (%f
%f)\n",u2mm(x),u2mm(y),u2mm(C.x),u2mm(C.y));
x1=C.x+round(cos(PIang/180)(xs-edg)-sin(PIang/180)ys); //find dist to
upper wire
y1=C.yround(sin(PIang/180)(xs-edg)cos(PIang/180)ys);
x2=C.xround(cos(PIang/180)(-xsedg)-sin(PIang/180)ys);
y2=C.yround(sin(PIang/180)(-xsedg)+cos(PIang/180)ys);
t1=Point2WireDistance(x,y,x1,y1,x2,y2);
dist=t1;
//printf("\tDist to upper wire (%f %f) (%f
%f):%f\n",u2mm(x1),u2mm(y1),u2mm(x2),u2mm(y2),u2mm(t1));
x1=C.x+round(cos(PIang/180)(xs-edg)-sin(PIang/180)(-ys)); //find dist
to lower wire
y1=C.yround(sin(PIang/180)(xs-edg)cos(PIang/180)(-ys));
x2=C.xround(cos(PIang/180)(-xsedg)-sin(PIang/180)(-ys));
y2=C.yround(sin(PIang/180)(-xsedg)+cos(PIang/180)(-ys));
t1=Point2WireDistance(x,y,x1,y1,x2,y2);
if(t1<dist) dist=t1;
//printf("\tDist to lower wire (%f %f) (%f
%f):%f\n",u2mm(x1),u2mm(y1),u2mm(x2),u2mm(y2),u2mm(t1));
x1=C.x+round(cos(PIang/180)(-xs)-sin(PIang/180)(ys-edg)); //find dist
to left wire
y1=C.yround(sin(PIang/180)(-xs)cos(PIang/180)(ys-edg));
x2=C.xround(cos(PIang/180)(-xs)-sin(PIang/180)(-ysedg));
y2=C.yround(sin(PIang/180)(-xs)cos(PIang/180)(-ys+edg));
t1=Point2WireDistance(x,y,x1,y1,x2,y2);
if(t1<dist) dist=t1;
//printf("\tDist to left wire (%f %f) (%f
%f):%f\n",u2mm(x1),u2mm(y1),u2mm(x2),u2mm(y2),u2mm(t1));
x1=C.x+round(cos(PIang/180)(xs)-sin(PIang/180)(ys-edg)); //find dist
to right wire
y1=C.yround(sin(PIang/180)(xs)cos(PIang/180)(ys-edg));
x2=C.xround(cos(PIang/180)(xs)-sin(PIang/180)(-ysedg));
y2=C.yround(sin(PIang/180)(xs)cos(PIang/180)(-ys+edg));
t1=Point2WireDistance(x,y,x1,y1,x2,y2);
if(t1<dist) dist=t1;
//printf("\tDist to right wire (%f %f) (%f
%f):%f\n",u2mm(x1),u2mm(y1),u2mm(x2),u2mm(y2),u2mm(t1));
if(edg)
{
x1=C.x+round(cos(PIang/180)(xs-edg)-sin(PIang/180)(ys-edg)); //circle
in upper right corner
y1=C.yround(sin(PIang/180)(xs-edg)cos(PIang/180)(ys-edg));
t=Point2PointDistance(x,y,x1,y1)-edg; // check dist to circle in upper
right corner
//printf("\tDist to upper right corner circle(%f
%f):%f\n",u2mm(x1),u2mm(y1),u2mm(t));
if(t<dist) dist=t;
x1=C.xround(cos(PIang/180)(xs-edg)-sin(PIang/180)(-ysedg));
//circle in lower right corner
y1=C.yround(sin(PIang/180)(xs-edg)cos(PIang/180)(-ys+edg));
t=Point2PointDistance(x,y,x1,y1)-edg; // check dist to circle in lower
right corner
//printf("\tDist to lower right corner circle(%f
%f):%f\n",u2mm(x1),u2mm(y1),u2mm(t));
if(t<dist) dist=t;
x1=C.xround(cos(PIang/180)(-xsedg)-sin(PIang/180)(-ys+edg));
//circle in lower left corner
y1=C.yround(sin(PIang/180)(-xsedg)cos(PIang/180)(-ysedg));
t=Point2PointDistance(x,y,x1,y1)-edg; // check dist to circle in lower
left corner
//printf("\tDist to lower left corner circle(%f
%f):%f\n",u2mm(x1),u2mm(y1),u2mm(t));
if(t<dist) dist=t;
x1=C.xround(cos(PIang/180)(-xsedg)-sin(PIang/180)(ys-edg));
//circle in upper left corner
y1=C.yround(sin(PIang/180)(-xsedg)+cos(PIang/180)(ys-edg));
t=Point2PointDistance(x,y,x1,y1)-edg; // check dist to circle in upper
left corner
//printf("\tDist to upper left corner circle(%f
%f):%f\n",u2mm(x1),u2mm(y1),u2mm(t));
if(t<dist) dist=t;
}
//printf("\tDistance=%f\n",u2mm(dist));
return dist;
}