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.
"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;
}
"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;
}