I have received an admission assignment for the Computer Science program, where I have to approach PI. To calculate pi I have to make a ratio between the area of a square, a circle, the total number of dots and the number of dots within the circle.
N = total number of dots
M = dots within the circle
The diameter is 400
The formula of the area of a circle
radius^2 * π or diameter^2 * π / 4
The formula of the area of a square
2*radius^2 or diameter^2
I had the formule ( M / N ) * 4
This is how I got it:
(d^2 * π / 4) : d^2 = M : N
π / 4 = M / N
π = ( M / N ) * 4
the problem is that I don't get pi as output, but about 14.2..
Does anyone know what I am doing wrong?
So in Processing I wrote the following code
float N = 0;
float M = 0;
void setup()
{
size(400, 400);
frameRate(90000);
background(255, 255, 255);
ellipse(200,200,400,400);
}
void draw()
{
/* Random x- en y-coordinate. */
float x = random(0,400);
float dx= (x-200);
float y = random(0,400);
float dy = (y-200);
float d = (float)(Math.sqrt(Math.pow(dx,2) + Math.pow(dy,2)));
/*Red in the circle*/
if(d <= 200 ){
stroke(255,0,0);
M++;
}
else{
stroke(0,255,0); /*green around the circle*/
N++;
}
point(x,y);
println
((M/N)*4);
}
The dots that land inside the circle also land in the square since the circle lays inside the square.
You need to do 4*M/(M+N).
Related
I'm currently working on a raycaster in Java, and so far, I have the floor correctly textured. The problem, however, is that the floor doesn't scroll. In other words, when I move the camera in the projection, the floor stays the same, yet the walls move as expected. I'm really not sure what I'm doing wrong. I took almost all the code from this reference. Note that I took some liberties when pasting the code in that I used some pseudocode.
I tried applying a player offset to the tileX and tileY variables, e.g., tileX += player.x, and all I got was a floor that scrolls far too quickly and incorrectly.
for every ray:
... // other stuff relating to the walls above here.
int start = (int)(wallY + wallHeight + 1);
double directionCos = cos(rad(ray.getAngle()));
double directionSin = sin(rad(ray.getAngle()));
int textureDim = 16;
for (int y = start; y < screenHeight; y++) {
double distance = screenHeight / (2.f * y - screenHeight);
distance /= cos(rad(player.getAngle()) - rad(ray.getAngle()));
// The source I grabbed the code from actually appends the player's x and y to the tileX and tileY variables, but this completely messes up the textures when I try to.
double tileX = distance * directionCos;
double tileY = distance * directionSin;
int textureX = Math.floorMod((int)(tileX * textureDim), textureDim);
int textureY = Math.floorMod((int)(tileY * textureDim), textureDim);
int rgb = floorTexture.getRGB(textureX, textureY);
projectionFloor.setRGB((int)wallX, y, rgb);
}
Below is an image of the floor.
Below is an animation visualizing the problem.
Below is an animation visualizing what happens if I try to apply a player position offset:
Fixed it on my own. Turns out that, yes, you do have to account for the player's position (shocker!); the source I got the code from just didn't do it correctly.
DTPP = distance to projection plane.
for every pixel y from wallY + wallHeight + 1 to projectionHeight:
double r = y - this.getPreferredSize().height / 2.f;
double d = (CAMERA_HEIGHT * DTPP / r) / ANGLE;
double tileX = CAMERA_X + d * RAY_COSANGLE;
double tileY = CAMERA_Y + d * RAY_SINANGLE;
int textureX = Math.floorMod((int) (tileX * TEXTURE_SIZE /
TEXTURE_SCALE), TEXTURE_SIZE);
int textureY = Math.floorMod((int) (tileY * TEXTURE_SIZE /
TEXTURE_SCALE), TEXTURE_SIZE);
... (drawing occurs here)
This is for a visualization I am working on. I want to divide a rectangle in N equal parts. I want these parts to have a width of say (min. 1px, max 1.5px), depending on the width of the rectangle and I want this division to end with a remainder of 0 (so I don't have a larger than the rest part).
I have tried implementing Modulo: https://processing.org/reference/modulo.html but I am not sure this is the correct way. Any ideas?
//Generates coordinates within each line.
for (int j = 0; j < line_coordinates.length; j++) {
//Positions start of line draw on random X coordinate.
float xv = component_x1 + (j * (component_length / line_coordinates.length+1));
float yv = line_height;
//Defines available with for each item in a component.
float item_availablewidth = component_length / line_coordinates.length+1;
//Creates vector with X coordinate and Y noise affected coordinate.
line_coordinates[j] = new PVector(xv, y);
rectMode(CENTER);
noStroke();
fill(232, 45, 34);
rect(line_coordinates[j].x,
line_coordinates[j].y - (line_height / 2),
item_availablewidth * item_randomwidthcoefficient,
line_height);
println("line_coordinates[j].x1",
line_coordinates[j].x - ((item_availablewidth * item_randomwidthcoefficient) / 2)); //This is where X starts.
println("line_coordinates[j].x2",
line_coordinates[j].x + ((item_availablewidth * item_randomwidthcoefficient) / 2)); //This is where X is supposed to end.
//This is the first method I tried but I found out this separation needs to be dynamic.
float drawnline_separation = 2;
float drawnline_total = (item_availablewidth * item_randomwidthcoefficient) / drawnline_separation;
println("drawnline_total",
drawnline_total);
//For loop divides each item in vertical -axidrawable- lines separating them by a max
for (int l = 0; l <= drawnline_total; l++) {
float drawnline_x = lerp(line_coordinates[j].x - ((item_availablewidth * item_randomwidthcoefficient) / 2),
line_coordinates[j].x + ((item_availablewidth * item_randomwidthcoefficient) / 2),
l/drawnline_total);
println("drawnline_x", drawnline_x);
stroke(23);
noFill();
//Draws line.
line(drawnline_x,
line_coordinates[j].y,
drawnline_x,
line_coordinates[j].y + 25 );
}
}
//This is the print I am getting.
line_coordinates[j].x1 346.42535
line_coordinates[j].x2 353.44092
drawnline_total 3.5077777
drawnline_x 346.42535
drawnline_x 348.42535
drawnline_x 350.42535
drawnline_x 352.42535
I hope I am being clear! Please let me know if my explanation is very confusing.
i have a mathematical problem. Im making a game where the user is a 12 year old kid. The child's goal is to calculate the area of a drawn shape. In easy and medium mode, the shapes are given and hard coded so they are not hardcore. in the hard mode 5 coordinates are randomly generated and here is where the problem comes. I need to make a shape which area is calculable by a 12 y/o child. With the random coordinates come various hard things, such as intersections, or odd points on a line connecting 2 other points and so. Is there any way to calculate and avoid such problems?
Here is my code which makes the random points + draws it on a dot grid in the application:
private void gameHard ()
{
//distance between points is 65 pixels, the numbers that are generated are 1-8
x1=(genRandomInt())*65;
x2=(genRandomInt())*65;
x3=(genRandomInt())*65;
x4=(genRandomInt())*65;
x5=(genRandomInt())*65;
y1=(genRandomInt())*65;
y2=(genRandomInt())*65;
y3=(genRandomInt())*65;
y4=(genRandomInt())*65;
y5=(genRandomInt())*65;
compareRCoordinates ();
areaImage = new JPanel ()
{
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.WHITE);
g2.fillRect(0,0,780,650);
g2.setColor(Color.BLACK);
int xnum = 65, ynum = 65;
for(ynum=65;ynum<650;ynum=ynum+65)
{
int x=0, y=0;
for(xnum = 65;xnum<780;xnum=xnum+65)
{
x = xnum-9;
y = ynum-9;
g2.fillOval(x,y,18,18);
}
xnum=xnum+65;
}
g2.setColor(Color.RED);
g2.setStroke(new BasicStroke(6));
g2.drawLine(x1,y1,x2,y2);
g2.drawLine(x2,y2,x3,y3);
g2.drawLine(x3,y3,x4,y4);
g2.drawLine(x4,y4,x5,y5);
g2.drawLine(x5,y5,x1,y1);
}
};
areaImage.setBounds(20,20,780,650);
areaImage.setBorder(BorderFactory.createLineBorder(Color.black));
this.add(areaImage);
roundsPlayed++;
}
Here's the outline of a fairly straightforward method.
Choose five distinct random points.
Calculate the centroid of the five points (that is, the average X co-ordinate and the average Y co-ordinate).
Calculate the angle from the centroid to each of the five original points. If one of the points happens to be the centroid, then pick any number at all (such as 0) as the angle.
Arrange the points in order of the angle calculated. Ties can be broken arbitrarily.
OK, the points now make a pentagon in the order you've arranged them (including a line segment from the last point to the first one). It's not necessarily convex, but it won't have any "crossing over". You can draw this on the screen.
And you can calculate the area as
( x1 * y2 + x2 * y3 + x3 * y4 + x4 * y5 + x5 * y1 - y1 * x2 - y2 * x3 - y3 * x4 - y4 * x5 - y5 * x1 ) / 2
My basic idea is I divide your 64 (8 by 8) possible points into 5 disjoint rectangular areas and pick one random point from each area. The areas are picked so that connecting the points in order will never cause any connecting lines to cross. It’s quite simple — maybe too simple?
x1 = genRandomInt(1, 3) * 65;
y1 = genRandomInt(1, 4) * 65;
x2 = genRandomInt(1, 3) * 65;
y2 = genRandomInt(5, 8) * 65;
x3 = genRandomInt(4, 8) * 65;
y3 = genRandomInt(6, 8) * 65;
x4 = genRandomInt(4, 8) * 65;
y4 = genRandomInt(4, 5) * 65;
x5 = genRandomInt(6, 8) * 65;
y5 = genRandomInt(1, 3) * 65;
Write genRandomInt(int from, int to) so that it returns a random int in the interval from from through to inclusive. In the code above I have between 10 and 15 possible points in each of the rectangular areas.
Using arrays for the coordinates facilitates.
One could use a random distance to the prior points so points are not near. I'll be math lazy and simply repeat selecting new random numbers till the random point is no longer near.
Finally I cheat and use java.awt.Polygon to check that the new candidate point is not inside the polygon till that.
Polygon one can draw, and even fill.
The fields:
int[] xs = new int[5]; // xs[0] till xs[4]
int[] ys = new int[5];
Polygon pentagon;
Picking random points:
final int NEAR = 20;
for (int i = 0; i < 5; ++i) {
// Pull random numbers for this i'th point till okay.
for (;;) {
xs[i] = random ...
ys[i] = random ...
// Check that the point is not inside the polygon till now:
if (i >= 3) {
Polygon polygon = new Polygon(xs, ys, i);
if (polygon.contains(xs[i], ys[i]) {
continue; // Inside
}
}
// Check that the point are apart:
boolean near = false;
for (int j = 0; j < i && !near; ++j) {
near = Math.abs(xs[i] - xs[j]) < NEAR
&& Math.abs(ys[i] - ys[j]) < NEAR;
}
if (near) {
continue; // Too near
}
break; // Found point i
}
}
pentagon = new Polygon(xs, ys, 5);
Drawing:
g2.setColor(Color.RED);
g2.setStroke(new BasicStroke(6));
g2.draw(pentagon);
g2.setColor(Color.TEAL);
g2.fill(pentagon);
... draw grid
As you might image there might be sufficient looping. Endless when the first four points cover the largest part of the screen.
I want to draw an arc using center point,starting point,ending point on opengl surfaceview.I have tried this given below code so far. This function draws the expected arc if we give the value for start_line_angle and end_line_angle manually (like start_line_angle=0 and end_line_angle=90) in degree.
But I need to draw an arc with the given co-ordinates(center point,starting point,ending point) and calculating the start_line_angle and end_line_angle programatically.
This given function draws an arc with the given parameters but not giving the desire result. I've wasted my 2 days for this. Thanks in advance.
private void drawArc(GL10 gl, float radius, float cx, float cy, float start_point_x, float start_point_y, float end_point_x, float end_point_y) {
gl.glLineWidth(1);
int start_line_angle;
double sLine = Math.toDegrees(Math.atan((cy - start_point_y) / (cx - start_point_x))); //normal trigonometry slope = tan^-1(y2-y1)/(x2-x1) for line first
double eLine = Math.toDegrees(Math.atan((cy - end_point_y) / (cx - end_point_x))); //normal trigonometry slope = tan^-1(y2-y1)/(x2-x1) for line second
//cast from double to int after round
int start_line_Slope = (int) (sLine + 0.5);
/**
* mapping the tiriogonometric angle system to glsurfaceview angle system
* since angle system in trigonometric system starts in anti clockwise
* but in opengl glsurfaceview angle system starts in clock wise and the starting angle is 90 degree of general trigonometric angle system
**/
if (start_line_Slope <= 90) {
start_line_angle = 90 - start_line_Slope;
} else {
start_line_angle = 360 - start_line_Slope + 90;
}
// int start_line_angle = 270;
// int end_line_angle = 36;
//casting from double to int
int end_line_angle = (int) (eLine + 0.5);
if (start_line_angle > end_line_angle) {
start_line_angle = start_line_angle - 360;
}
int nCount = 0;
float[] stVertexArray = new float[2 * (end_line_angle - start_line_angle)];
float[] newStVertextArray;
FloatBuffer sampleBuffer;
// stVertexArray[0] = cx;
// stVertexArray[1] = cy;
for (int nR = start_line_angle; nR < end_line_angle; nR++) {
float fX = (float) (cx + radius * Math.sin((float) nR * (1 * (Math.PI / 180))));
float fY = (float) (cy + radius * Math.cos((float) nR * (1 * (Math.PI / 180))));
stVertexArray[nCount * 2] = fX;
stVertexArray[nCount * 2 + 1] = fY;
nCount++;
}
//taking making the stVertextArray's data in reverse order
reverseArray = new float[stVertexArray.length];//-2 so that no repeatation occurs of first value and end value
int count = 0;
for (int i = (stVertexArray.length) / 2; i > 0; i--) {
reverseArray[count] = stVertexArray[(i - 1) * 2 + 0];
count++;
reverseArray[count] = stVertexArray[(i - 1) * 2 + 1];
count++;
}
//reseting the counter to initial value
count = 0;
int finalArraySize = stVertexArray.length + reverseArray.length;
newStVertextArray = new float[finalArraySize];
/**Now adding all the values to the single newStVertextArray to draw an arc**/
//adding stVertextArray to newStVertextArray
for (float d : stVertexArray) {
newStVertextArray[count++] = d;
}
//adding reverseArray to newStVertextArray
for (float d : reverseArray) {
newStVertextArray[count++] = d;
}
Log.d("stArray", stVertexArray.length + "");
Log.d("reverseArray", reverseArray.length + "");
Log.d("newStArray", newStVertextArray.length + "");
ByteBuffer bBuff = ByteBuffer.allocateDirect(newStVertextArray.length * 4);
bBuff.order(ByteOrder.nativeOrder());
sampleBuffer = bBuff.asFloatBuffer();
sampleBuffer.put(newStVertextArray);
sampleBuffer.position(0);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(2, GL10.GL_FLOAT, 0, sampleBuffer);
gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, nCount * 2);
gl.glLineWidth(1);
}
To begin with the trigonometry you may not simply use the atan to find degrees of the angle. You need to check what quadrant the vector is in and increase or decrease the result you get from atan. Better yet use atan2 which should include both dx and dy and do the job for you.
You seem to create the buffer so that a point is created per degree. This is not the best solution as for large radius that might be too small and for small radius this is way too much. Tessellation should include the radius as well such that number of points N is N = abs((int)(deltaAngle*radius*tessellationFactor)) then use angleFragment = deltaAngle/N but make sure that N is greater then 0 (N = N?N:1). The buffer size is then 2*(N+1) of floats and the iteration if for(int i=0; i<=N; i++) angle = startAngle + angleFragment*i;.
As already pointed out you need to define the radius of the arc. It is quite normal to use an outside source the way you do and simply force it to that value but use the 3 points for center and the two borders. Some other options that usually make sense are:
getting the radius from the start line
getting the radius from the shorter of the two lines
getting the average of the two
interpolate the two to get an elliptic curve (explained below)
To interpolate the radius you need to get the two radiuses startRadius and endRadius. Then you need to find the overall radius which was already used as deltaAngle above (watch out when computing this one, it is more complicated as it seems, for instance drawing from 320 degrees to 10 degrees results in deltaAngle = 50). Anyway the radius for a specific point is then simply radius = startRadius + (endRadius-startRadius)*abs((angleFragment*i)/deltaAngle). This represents a simple linear interpolation in polar coordinate system which is usually used to interpolate vector in matrices and is the core functionality to get nice animations.
There are some other ways of getting the arc points which may be better performance wise but I would not suggest them unless and until you need to optimize your code which should be very late in production. You may simply keep stepping toward the next point and correcting the radius (this is only a concept):
vec2 start, end, center; // input values
float radius; // input value
// making the start and end relative to center
start -= center;
end -= center;
vec2 current = start/length(start) * radius; // current position starts in first vector
vec2 target = end/length(end) * radius; // should be the last point
outputBuffer[0] = current+center; // insert the first point
for(int i=1;; i++) { // "break" will need to exit the loop, we need index only for the buffer
vec2 step = vec2(current.y, -(current.x)); // a tangential vector from current start point according to center
step = step/length(step) / tessellationScale; // normalize and apply tessellation
vec2 next = current + step; // move tangentially
next = next/length(next) * radius; // normalize and set the
if(dot(current-target, next-target) > .0) { // when we passed the target vector
current = next; // set the current point
outputBuffer[i] = current+center; // insert into buffer
}
else {
current = target; // simply use the target now
outputBuffer[i] = current+center; // insert into buffer
break; // exit
}
}
I am working on the problem of dividing an ellipse into equal sized segments. This question has been asked but the answers suggested numerical integration so that I what I'm attempting. This code short-circuits the sectors so the integration itself should never cover more than 90 degrees. The integration itself is being done by totaling the area of intermediate triangles. Below is the code I have tried, but it is sweeping more than 90 degrees in some cases.
public class EllipseModel {
protected double r_x;
protected double r_y;
private double a,a2;
private double b,b2;
boolean flip;
double area;
double sector_area;
double radstep;
double rot;
int xp,yp;
double deviation;
public EllipseModel(double r_x, double r_y, double deviation)
{
this.r_x = r_x;
this.r_y = r_y;
this.deviation = deviation;
if (r_x < r_y) {
flip = true;
a = r_y;
b = r_x;
xp = 1;
yp = 0;
rot = Math.PI/2d;
} else {
flip = false;
xp = 0;
yp = 1;
a = r_x;
b = r_y;
rot = 0d;
}
a2 = a * a;
b2 = b * b;
area = Math.PI * r_x * r_y;
sector_area = area / 4d;
radstep = (2d * deviation) / a;
}
public double getArea() {
return area;
}
public double[] getSweep(double sweep_area)
{
System.out.println(String.format("getSweep(%f) a = %f b = %f deviation = %f",sweep_area,a,b,deviation));
double[] ret = new double[2];
double[] next = new double[2];
double t_base, t_height, swept,x_mid,y_mid;
double t_area;
sweep_area = sweep_area % area;
if (sweep_area < 0d) {
sweep_area = area + sweep_area;
}
if (sweep_area == 0d) {
ret[0] = r_x;
ret[1] = 0d;
return ret;
}
double sector = Math.floor(sweep_area/sector_area);
double theta = Math.PI * sector/2d;
double theta_last = theta;
System.out.println(String.format("- Theta start = %f",Math.toDegrees(theta)));
ret[xp] = a * Math.cos(theta + rot);
ret[yp] = (1 + (((theta / Math.PI) % 2d) * -2d)) * Math.sqrt((1 - ( (ret[xp] * ret[xp])/a2)) * b2);
next[0] = ret[0];
next[1] = ret[1];
swept = sector * sector_area;
System.out.println(String.format("- Sweeping for %f sector_area=%f",sweep_area-swept,sector_area));
int c = 0;
while(swept < sweep_area) {
c++;
ret[0] = next[0];
ret[1] = next[1];
theta_last = theta;
theta += radstep;
// calculate next point
next[xp] = a * Math.cos(theta + rot);
next[yp] = (1 + (((theta / Math.PI) % 2d) * -2d)) * // selects +/- sqrt
Math.sqrt((1 - ( (ret[xp] * ret[xp])/a2)) * b2);
// calculate midpoint
x_mid = (ret[xp] + next[xp]) / 2d;
y_mid = (ret[yp] + next[yp]) / 2d;
// calculate triangle metrics
t_base = Math.sqrt( ( (ret[0] - next[0]) * (ret[0] - next[0]) ) + ( (ret[1] - next[1]) * (ret[1] - next[1])));
t_height = Math.sqrt((x_mid * x_mid) + (y_mid * y_mid));
// add triangle area to swept
t_area = 0.5d * t_base * t_height;
swept += t_area;
}
System.out.println(String.format("- Theta end = %f (%d)",Math.toDegrees(theta_last),c));
return ret;
}
}
In the output I see the following case where it sweeps over 116 degrees.
getSweep(40840.704497) a = 325.000000 b = 200.000000 deviation = 0.166667
- Theta start = 0.000000
- Sweeping for 40840.704497 sector_area=51050.880621
- Theta end = 116.354506 (1981)
Is there any way to fix the integration formula to create a function that returns the point on an ellipse that has swept a given area? The application that is using this code divides the total area by the number of segments needed, and then uses this code to determine the angle where each segment starts and ends. Unfortunately it doesn't work as intended.
* edit *
I believe the above integration failed because the base and height formula's aren't correct.
No transformation needed use parametric equations for ellipse ...
x=x0+rx*cos(a)
y=y0+ry*sin(a)
where a = < 0 , 2.0*M_PI >
if you divide ellipse by lines from center to x,y from above equation
and angle a is evenly encreased
then the segments will have the same size
btw. if you apply affine transform you will get the same result (even the same equation)
This code will divide ellipse to evenly sized chunks:
double a,da,x,y,x0=0,y0=0,rx=50,ry=20; // ellipse x0,y0,rx,ry
int i,N=32; // divided to N = segments
da=2.0*M_PI/double(N);
for (a=0.0,i=0;i<N;i++,a+=da)
{
x=x0+(rx*cos(a));
y=y0+(ry*sin(a));
// draw_line(x0,y0,x,y);
}
This is what it looks like for N=5
[edit1]
I do not understood from your comment what exactly you want to achieve now
sorry but my English skills are horrible
ok I assume these two possibilities (if you need something different please specify closer)
0.but first some global or member stuff needed
double x0,y0,rx,ry; // ellipse parameters
// [Edit2] sorry forgot to add these constants but they are I thin straight forward
const double pi=M_PI;
const double pi2=2.0*M_PI;
// [/Edit2]
double atanxy(double x,double y) // atan2 return < 0 , 2.0*M_PI >
{
int sx,sy;
double a;
const double _zero=1.0e-30;
sx=0; if (x<-_zero) sx=-1; if (x>+_zero) sx=+1;
sy=0; if (y<-_zero) sy=-1; if (y>+_zero) sy=+1;
if ((sy==0)&&(sx==0)) return 0;
if ((sx==0)&&(sy> 0)) return 0.5*pi;
if ((sx==0)&&(sy< 0)) return 1.5*pi;
if ((sy==0)&&(sx> 0)) return 0;
if ((sy==0)&&(sx< 0)) return pi;
a=y/x; if (a<0) a=-a;
a=atan(a);
if ((x>0)&&(y>0)) a=a;
if ((x<0)&&(y>0)) a=pi-a;
if ((x<0)&&(y<0)) a=pi+a;
if ((x>0)&&(y<0)) a=pi2-a;
return a;
}
1.is point inside segment ?
bool is_pnt_in_segment(double x,double y,int segment,int segments)
{
double a;
a=atanxy(x-x0,y-y0); // get sweep angle
a/=2.0*M_PI; // convert angle to a = <0,1>
if (a>=1.0) a=0.0; // handle extreme case where a was = 2 Pi
a*=segments; // convert to segment index a = <0,segments)
a-=double(segment );
// return floor(a); // this is how to change this function to return points segment id
// of course header should be slightly different: int get_pnt_segment_id(double x,double y,int segments)
if (a< 0.0) return false; // is lower then segment
if (a>=1.0) return false; // is higher then segment
return true;
}
2.get edge point of segment area
void get_edge_pnt(double &x,double &y,int segment,int segments)
{
double a;
a=2.0*M_PI/double(segments);
a*=double(segment); // this is segments start edge point
//a*=double(segment+1); // this is segments end edge point
x=x0+(rx*cos(a));
y=y0+(ry*sin(a));
}
for booth:
x,y is point
segments number of division segments.
segment is sweep-ed area < 0,segments )
Apply an affine transformation to turn your ellipse into a circle, preferrably the unit circle. Then split that into equal sized segments, before you apply the inverse transform. The transformation will scale all areas (as opposed to lengths) by the same factor, so equal area translates to equal area.