[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: gEDA-user: pcb GL can't render stretched arcs
I had a quick look at the routine and must say that I did not grasp the code.
It is probably due to some heavy optimizations.
My approach had been more in the line of:
// Assumption done on ArcType in that the StartAngle attribute is the
// arcs CCW rotation with zero meaning that attribute Width is along X
// and attribute Height is along Y
bool IsPointOnArc (float X, float Y, float Radius, ArcTypePtr Arc)
// Point is defined as a circle loctaed at X,Y with radius Radius
{
double pdx, pdx2, pdy, pdy2, cosAlpha, sinAlpha, al2, as2, bl2, bs2;
double Al, As, Bl, Bs, Cl, Cs; // Should be part of ARC struct and
updated accordingly.
double resSmall, resLarge;
// Translate point coordinates to local arc origin
pdx = X - Arc->X;
pdx2 = pdx*pdx;
pdy = Y - Arc->Y;
pdy2 = pdy*pdy;
// This could have been optimized if Al, As, Bl, Bs, Cl and Cs was
part of the Arc and only
// updated when needed, e.g at creation of ARC or modification of ARC.
// Note to myself, since the larger and smaller ellipses is a
function of the Radius it will not
// work unless the ARC had a memory with respect to which radius
have been used earlier, e.g let
// the ARC worry about how/when to calculate these values.
// Note this whole procedure is based on the equation governing a
rotated ellipse, see:
// http://www.maa.org/joma/Volume8/Kalman/General.html
// Here we calculate the two boundary ellipses, one on the inside
(As, Bs, Cs) and one on the outside
// (Al, Bl, Cl) where the geometry is given by the ellipse Height,
Width and its thickness.
// The radius of the point is added to the boundary in order to use
the point coordinates
// in the equations.
// Generally the eq is: 1-Ax²+Bx*y+C*x²= 0 and a given points
coordinates will result in the lVal
// > 0 for inside the ellipse,
// = 0 for on the ellipse
// < 0 for outside the ellipse
cosAlpha=cos(Arc->StartAngle*M_PI/180);
sinAlpha=sin(Arc->StartAngle*M_PI/180);
al2 = 1/((Arc->Width+Arc->Thickness/2+Radius)*(Arc->Width+Arc->Thickness/2+Radius));
bl2 = 1/((Arc->Height+Arc->Thickness/2+Radius)*(Arc->Height+Arc->Thickness/2+Radius));
as2 = 1/((Arc->Width-Arc->Thickness/2-Radius)*(Arc->Width-Arc->Thickness/2-Radius));
bs2 = 1/((Arc->Height-Arc->Thickness/2-Radius)*(Arc->Height-Arc->Thickness/2-Radius));
Al = cosAlpha*cosAlpha*al2+sinAlpha*sinAlpha*bl2;
Bl = -2*cosAlpha*sinAlpha*(al2-bl2);
Cl = sinAlpha*sinAlpha*al2+cosAlpha*cosAlpha*bl2;
As = cosAlpha*cosAlpha*as2+sinAlpha*sinAlpha*bs2;
Bs = -2*cosAlpha*sinAlpha*(as2-bs2);
Cs = sinAlpha*sinAlpha*as2+cosAlpha*cosAlpha*bs2;
resSmall = 1-As*pdx2-Bs*pdx*pdy-Cs*pdy2;
resLarge = 1-Al*pdx2-Bl*pdx*pdy-Cl*pdy2;
// For point to be on arc -> outside the small ellipse and inside
the large ellipse
if((resSmall<=0) && (resLarge>=0))
return (true);
else
return (false);
}
_______________________________________________
geda-user mailing list
geda-user@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-user