If I want to generate a bunch of points distributed uniformly around a circle, I can do this (python):
r = 5 #rad
I'm sure this thread is long dead by now, but I just came across this issue and this was the closest that came to a solution.
I started with Dave's answer here, but I noticed that it wasn't really answering the poster's question. It wasn't dividing the ellipse equally by arc lengths, but by angle.
Anyway, I made some adjustments to his (awesome) work to get the ellipse to divide equally by arc length instead (written in C# this time). If you look at the code, you'll see some of the same stuff -
void main()
{
List pointsInEllipse = new List();
// Distance in radians between angles measured on the ellipse
double deltaAngle = 0.001;
double circumference = GetLengthOfEllipse(deltaAngle);
double arcLength = 0.1;
double angle = 0;
// Loop until we get all the points out of the ellipse
for (int numPoints = 0; numPoints < circumference / arcLength; numPoints++)
{
angle = GetAngleForArcLengthRecursively(0, arcLength, angle, deltaAngle);
double x = r1 * Math.Cos(angle);
double y = r2 * Math.Sin(angle);
pointsInEllipse.Add(new Point(x, y));
}
}
private double GetLengthOfEllipse()
{
// Distance in radians between angles
double deltaAngle = 0.001;
double numIntegrals = Math.Round(Math.PI * 2.0 / deltaAngle);
double radiusX = (rectangleRight - rectangleLeft) / 2;
double radiusY = (rectangleBottom - rectangleTop) / 2;
// integrate over the elipse to get the circumference
for (int i = 0; i < numIntegrals; i++)
{
length += ComputeArcOverAngle(radiusX, radiusY, i * deltaAngle, deltaAngle);
}
return length;
}
private double GetAngleForArcLengthRecursively(double currentArcPos, double goalArcPos, double angle, double angleSeg)
{
// Calculate arc length at new angle
double nextSegLength = ComputeArcOverAngle(majorRadius, minorRadius, angle + angleSeg, angleSeg);
// If we've overshot, reduce the delta angle and try again
if (currentArcPos + nextSegLength > goalArcPos) {
return GetAngleForArcLengthRecursively(currentArcPos, goalArcPos, angle, angleSeg / 2);
// We're below the our goal value but not in range (
} else if (currentArcPos + nextSegLength < goalArcPos - ((goalArcPos - currentArcPos) * ARC_ACCURACY)) {
return GetAngleForArcLengthRecursively(currentArcPos + nextSegLength, goalArcPos, angle + angleSeg, angleSeg);
// current arc length is in range (within error), so return the angle
} else
return angle;
}
private double ComputeArcOverAngle(double r1, double r2, double angle, double angleSeg)
{
double distance = 0.0;
double dpt_sin = Math.Pow(r1 * Math.Sin(angle), 2.0);
double dpt_cos = Math.Pow(r2 * Math.Cos(angle), 2.0);
distance = Math.Sqrt(dpt_sin + dpt_cos);
// Scale the value of distance
return distance * angleSeg;
}