[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