Skip to content

Instantly share code, notes, and snippets.

@se5a
Last active May 13, 2023 00:09
Show Gist options
  • Save se5a/b51de5876865bd8b2f6c6ec47557289f to your computer and use it in GitHub Desktop.
Save se5a/b51de5876865bd8b2f6c6ec47557289f to your computer and use it in GitHub Desktop.
Using matrix transforms for ellipse arcs.
public static DVec.Vector2[] EllipseFullMtxSweep(double semiMaj, double eccentricity, double tilt, double start,
double sweep, int numPoints)
{
//convert ellipse angles to circle angles.
double b = semiMaj * Math.Sqrt(1 - eccentricity * eccentricity);
start = Math.Atan(semiMaj / b * Math.Tan(start));
sweep = Math.Atan(semiMaj / b * Math.Tan(sweep));
double end = start + sweep;
double Δθ = 2 * Math.PI / (numPoints - 1) * Math.Sign(sweep); //arc increment for a whole circle
numPoints = (int)Math.Abs(sweep / Δθ); //numpoints for just the arc
DVec.Vector2[] points = new DVec.Vector2[numPoints + 1];
double linEcc = Math.Sqrt(semiMaj * semiMaj - b * b);
double θ = 0;
double x = 0;
double y = 0;
for (int i = 0; i < numPoints; i++)
{
θ = start + Δθ * i;
x = semiMaj * Math.Cos(θ);
y = semiMaj * Math.Sin(θ);
points[i] = new DVec.Vector2(x, y);
}
x = semiMaj * Math.Cos(end);
y = semiMaj * Math.Sin(end);
points[numPoints] = new DVec.Vector2(x, y);
Matrix mirMtx = Matrix.IDMirror(true, false);
Matrix scalemtx = Matrix.IDScale(1, 1 - eccentricity);
Matrix moveMtx = Matrix.IDTranslate(-linEcc, 0);
Matrix rotMtx = Matrix.IDRotate(tilt);
Matrix endMtx = mirMtx * moveMtx * scalemtx * rotMtx;
points = endMtx.Transform(points);
return points;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment