Rotating points around another arbitrary point - c

Given the following test code inside a function:
int orientation = 0; // increments up to 359, then loops to 0
int tempx, tempy;
float radians = orientation * (M_PI / 180);
tempx = point->x;
tempy = point->y;
tempx = (int) (tempx * cos(radians) - tempy * sin(radians));
tempy = (int) (tempx * sin(radians) + tempy * cos(radians));
tempx = tempx + origin->x;
tempy = tempy + origin->y;
With the following points (relative to origin): (-100, 0), (0, -100), (0, 100) I get this strange plot:
The blue and green lines are overlapping paths. The intersection at the middle (with the barely-visible yellow point) is the origin. All points are in the correct position when orientation is 0 or 180 but in a non-circular path at all other angles. I've done plenty of linear algebra in my time, but this has me stumped. I'm not sure if I'm overlooking something in C itself, or if I'm just not seeing the problem.

You are reusing tempx after rotating it. Try the following instead:
tempx = (int) (point->x* cos(radians) - point->y* sin(radians));
tempy = (int) (point->x* sin(radians) + point->y* cos(radians));
and see if that fixes things or not.

Related

Rotate Custom Object in Animation Loop

I created some Functions, these will draw Rectangles, Circles, Hexagons etc.
One of them looks like this:
rotation = 45;
function hex(hex_sides, hex_size, hex_color){
x = ctx.canvas.width/2;
y = ctx.canvas.height/2;
ctx.save();
ctx.rotate(rotation*Math.PI/180);
ctx.translate(ctx.canvas.width/2, ctx.canvas.height/2);
ctx.moveTo(x + hex_size * Math.cos(0), y + hex_size * Math.sin(0));
ctx.restore();
for (i = 0; i < hex_sides+1; i++) {
ctx.lineTo(x + hex_size * Math.cos(i * 2 * Math.PI / hex_sides), y + hex_size * Math.sin(i * 2 * Math.PI / hex_sides));
}
ctx.strokeStyle = hex_color;
ctx.stroke();
}
Now i call the Functions to Draw the Shapes inside my animation loop.
function loop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
circle(200);
circle(220);
hex(6, 180, "#fff");
rotation += 0.4;
requestAnimationFrame(loop);
}
I'm incrementing the var rotation inside the loop but it does not rotate the whole shape but just one line of it instead. Other Shapes i cant get to rotate at all.
I think i got a wrong approach, maybe because of my confusion about .save() and .restore() or .beginPath() and .closePath().
In General the behaviour is very strange when i start to use .translate() and .rotate()
The entire Code is here.
UPDATE
It is definitely something about this line:
ctx.translate(ctx.canvas.width/2, ctx.canvas.height/2);
Somehow it does not translate correctly. The rotation now happens around the right middle side of the normal shape position but i want the rotation around its own axis.
I changed the hex() function to:
ctx.save();
ctx.translate(ctx.canvas.width/2, ctx.canvas.height/2);
ctx.rotate(rotation*Math.PI/180);
ctx.moveTo(x + hex_size * Math.cos(0), y + hex_size * Math.sin(0));
for (i = 0; i < hex_sides+1; i++) {
ctx.lineTo(x + hex_size * Math.cos(i * 2 * Math.PI / hex_sides), y + hex_size * Math.sin(i * 2 * Math.PI / hex_sides));
}
ctx.strokeStyle = hex_color;
ctx.stroke();
ctx.restore();
Again, entire Code is here.
Nevermind... figured it out, i have forgotten to substract half of the shapes width from the translation point and also the order seems to be more important then i tought.
Working Code
function hex(hex_sides, hex_size, hex_color){
x = ctx.canvas.width/2;
y = ctx.canvas.height/2;
ctx.save();
ctx.translate(x,y);
ctx.rotate(rotation*Math.PI/180);
//ctx.moveTo(x + hex_size * Math.cos(0), y + hex_size * Math.sin(0));
ctx.moveTo(0,0);
for (i = 0; i < hex_sides+1; i++) {
ctx.lineTo(x/hex_size + hex_size * Math.cos(i * 2 * Math.PI / hex_sides), y/hex_size + hex_size * Math.sin(i * 2 * Math.PI / hex_sides));
}
ctx.strokeStyle = hex_color;
ctx.stroke();
ctx.restore();
}

How to rotate a pixel/point around (0, 0) in C? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I already have the formula for rotating (px, py) around (ox, oy) by angle theta:
p'x = cos(theta) * (px-ox) - sin(theta) * (py-oy) + ox
p'y = sin(theta) * (px-ox) + cos(theta) * (py-oy) + oy
But when I set theta to:
double theta = 5 * PI / 180;
My point stays on the starting point link: (5, 5), whilst when I set theta to:
double theta = 6 * PI / 180;
It starts rotating like a link: square. I know that's supposed to happen because command prompt is like a huge monitor and there can't be a circle, but how can I make it rotate any point I set it to? For example the 6 * PI / 180 above doesn't work when my dot is link: (2, 2).
EDIT: ox, oy are (0, 0).
You don't show your code, but I guess that your code looks like this:
int x = 5;
int y = 5;
double a = 6 * PI / 180;
int i;
for (i = 0; i < 72; i++) {
int xx = round(x);
int yy = round(y);
putpixel(xx, yy, '*');
x = round(xx * cos(a) - yy * sin(a));
y = round(xx * sin(a) + yy * cos(a));
}
The variables could also be double, but the important thing here is that you round an thereby, depending on your radius and angle, cancel the distance you have covered by rotating. I can reproduce the screenshots you show with the code above.
The solution is to keep the fractional floating-point values throughout and to convert to integer only for printing:
double x = 5.0; // unrounded actual coordinates
double y = 5.0;
double a = 5 * PI / 180;
int i;
for (i = 0; i < 72; i++) {
int ix = rint(x); // temporary integers for plotting
int iy = rint(y);
double nx, ny; // temporary variables for update
putpixel(x, y, '*');
nx = x * cos(a) - y * sin(a);
ny = x * sin(a) + y * cos(a);
x = nx;
y = ny;
}
This gives a nice, round circle. If you want to draw a pixel circle with integer coordinates, have a look at the Midpoint algorithm.

How to implement adaptive subdivision algorithm for curve in C

My homework is to write a C program with openGL/Glut which, after getting groups of 4 points by mouse click (points with 3 coordinates), should draw a bezier curve with adaptive algorithm. At a theoretical level it's clear how the algorithm works but I don't know how to put that in C code. I mean that at lesson we saw that the 4 control points could have a shape similar to a "trapeze" and then the algorithm calculates the two "heights" and then checks if they satisfy a tollerance. The problem is that the user might click everywhere in the screen and the points might not have trapeze-like shape...so, where can I start from? This is all I have
This is the cole I have written, which is called each time a control point is added:
if (bezierMode == CASTELJAU_ADAPTIVE) {
glColor3f (0.0f, 0.8f, 0.4f); /* draw adaptive casteljau curve in green */
for(i=0; i+3<numCV; i += 3)
adaptiveDeCasteljau3(CV, i, 0.01);
}
void adaptiveDeCasteljau3(float CV[MAX_CV][3], int position, float tolerance) {
float x01 = (CV[position][0] + CV[position+1][0]) / 2;
float y01 = (CV[position][1] + CV[position+1][1]) / 2;
float x12 = (CV[position+1][0] + CV[position+2][0]) / 2;
float y12 = (CV[position+1][1] + CV[position+2][1]) / 2;
float x23 = (CV[position+2][0] + CV[position+3][0]) / 2;
float y23 = (CV[position+2][1] + CV[position+3][1]) / 2;
float x012 = (x01 + x12) / 2;
float y012 = (y01 + y12) / 2;
float x123 = (x12 + x23) / 2;
float y123 = (y12 + y23) / 2;
float x0123 = (x012 + x123) / 2;
float y0123 = (y012 + y123) / 2;
float dx = CV[3][0] - CV[0][0];
float dy = CV[3][1] - CV[0][1];
float d2 = fabs(((CV[1][0] - CV[3][0]) * dy - (CV[1][1] - CV[3][1]) * dx));
float d3 = fabs(((CV[2][0] - CV[3][0]) * dy - (CV[2][1] - CV[3][1]) * dx));
if((d2 + d3)*(d2 + d3) < tolerance * (dx*dx + dy*dy)) {
glBegin(GL_LINE_STRIP);
glVertex2f(x0123, y0123);
glEnd();
return;
}
float tmpLEFT[4][3];
float tmpRIGHT[4][3];
tmpLEFT[0][0] = CV[0][0];
tmpLEFT[0][1] = CV[0][1];
tmpLEFT[1][0] = x01;
tmpLEFT[1][1] = y01;
tmpLEFT[2][0] = x012;
tmpLEFT[2][1] = y012;
tmpLEFT[3][0] = x0123;
tmpLEFT[3][1] = y0123;
tmpRIGHT[0][0] = x0123;
tmpRIGHT[0][1] = y0123;
tmpRIGHT[1][0] = x123;
tmpRIGHT[1][1] = y123;
tmpRIGHT[2][0] = x23;
tmpRIGHT[2][1] = y23;
tmpRIGHT[3][0] = CV[3][0];
tmpRIGHT[3][1] = CV[3][1];
adaptiveDeCasteljau3(tmpLEFT, 0, tolerance);
adaptiveDeCasteljau3(tmpRIGHT, 0, tolerance);
}
and obviously nothing is drawn. Do you have any idea?
the Begin / End should engulf your whole loop, not being inside for each isolated vertex !

Cheap way of calculating cubic bezier length

An analytical solution for cubic bezier length
seems not to exist, but it does not mean that
coding a cheap solution does not exist. By cheap I mean something like in the range of 50-100 ns (or less).
Does someone know anything like that? Maybe in two categories:
1) less error like 1% but more slow code.
2) more error like 20% but faster?
I scanned through google a bit but it doesn't
find anything which looks like a nice solution. Only something like divide on N line segments
and sum the N sqrt - too slow for more precision,
and probably too inaccurate for 2 or 3 segments.
Is there anything better?
Another option is to estimate the arc length as the average between the chord and the control net. In practice:
Bezier bezier = Bezier (p0, p1, p2, p3);
chord = (p3-p0).Length;
cont_net = (p0 - p1).Length + (p2 - p1).Length + (p3 - p2).Length;
app_arc_length = (cont_net + chord) / 2;
You can then recursively split your spline segment into two segments and calculate the arc length up to convergence. I tested myself and it actually converges pretty fast. I got the idea from this forum.
Simplest algorithm: flatten the curve and tally euclidean distance. As long as you want an approximate arc length, this solution is fast and cheap. Given your curve's coordinate LUT—you're talking about speed, so I'm assuming you use those, and don't constantly recompute the coordinates—it's a simple for loop with a tally. In generic code, with a dist function that computes the euclidean distance between two points:
var arclength = 0,
last=LUT.length-1,
i;
for (i=0; i<last; i++) {
arclength += dist(LUT[i], LUT[i+1]);
}
Done. arclength is now the approximate arc length based on the maximum number of segments you can form in the curve based on your LUT. Need things faster with a larger potential error? Control the segment count.
var arclength = 0,
segCount = ...,
last=LUT.length-2,
step = last/segCount,
s, i;
for (s=0; s<=segCount; s++) {
i = (s*step/last)|0;
arclength += dist(LUT[i], LUT[i+1]);
}
This is pretty much the simplest possible algorithm that still generates values that come even close to the true arc length. For anything better, you're going to have to use more expensive numerical approaches (like the Legendre-Gauss quadrature technique).
If you want to know why, hit up the arc length section of "A Primer on Bézier Curves".
in my case a fast and valid approach is this. (Rewritten in c# for Unity3d)
public static float BezierSingleLength(Vector3[] points){
var p0 = points[0] - points[1];
var p1 = points[2] - points[1];
var p2 = new Vector3();
var p3 = points[3]-points[2];
var l0 = p0.magnitude;
var l1 = p1.magnitude;
var l3 = p3.magnitude;
if(l0 > 0) p0 /= l0;
if(l1 > 0) p1 /= l1;
if(l3 > 0) p3 /= l3;
p2 = -p1;
var a = Mathf.Abs(Vector3.Dot(p0,p1)) + Mathf.Abs(Vector3.Dot(p2,p3));
if(a > 1.98f || l0 + l1 + l3 < (4 - a)*8) return l0+l1+l3;
var bl = new Vector3[4];
var br = new Vector3[4];
bl[0] = points[0];
bl[1] = (points[0]+points[1]) * 0.5f;
var mid = (points[1]+points[2]) * 0.5f;
bl[2] = (bl[1]+mid) * 0.5f;
br[3] = points[3];
br[2] = (points[2]+points[3]) * 0.5f;
br[1] = (br[2]+mid) * 0.5f;
br[0] = (br[1]+bl[2]) * 0.5f;
bl[3] = br[0];
return BezierSingleLength(bl) + BezierSingleLength(br);
}
I worked out the closed form expression of length for a 3 point Bezier (below). I've not attempted to work out a closed form for 4+ points. This would most likely be difficult or complicated to represent and handle. However, a numerical approximation technique such as a Runge-Kutta integration algorithm (see my Q&A here for details) would work quite well by integrating using the arc length formula.
Here is some Java code for the arc length of a 3 point Bezier, with points a,b, and c.
v.x = 2*(b.x - a.x);
v.y = 2*(b.y - a.y);
w.x = c.x - 2*b.x + a.x;
w.y = c.y - 2*b.y + a.y;
uu = 4*(w.x*w.x + w.y*w.y);
if(uu < 0.00001)
{
return (float) Math.sqrt((c.x - a.x)*(c.x - a.x) + (c.y - a.y)*(c.y - a.y));
}
vv = 4*(v.x*w.x + v.y*w.y);
ww = v.x*v.x + v.y*v.y;
t1 = (float) (2*Math.sqrt(uu*(uu + vv + ww)));
t2 = 2*uu+vv;
t3 = vv*vv - 4*uu*ww;
t4 = (float) (2*Math.sqrt(uu*ww));
return (float) ((t1*t2 - t3*Math.log(t2+t1) -(vv*t4 - t3*Math.log(vv+t4))) / (8*Math.pow(uu, 1.5)));
public float FastArcLength()
{
float arcLength = 0.0f;
ArcLengthUtil(cp0.position, cp1.position, cp2.position, cp3.position, 5, ref arcLength);
return arcLength;
}
private void ArcLengthUtil(Vector3 A, Vector3 B, Vector3 C, Vector3 D, uint subdiv, ref float L)
{
if (subdiv > 0)
{
Vector3 a = A + (B - A) * 0.5f;
Vector3 b = B + (C - B) * 0.5f;
Vector3 c = C + (D - C) * 0.5f;
Vector3 d = a + (b - a) * 0.5f;
Vector3 e = b + (c - b) * 0.5f;
Vector3 f = d + (e - d) * 0.5f;
// left branch
ArcLengthUtil(A, a, d, f, subdiv - 1, ref L);
// right branch
ArcLengthUtil(f, e, c, D, subdiv - 1, ref L);
}
else
{
float controlNetLength = (B-A).magnitude + (C - B).magnitude + (D - C).magnitude;
float chordLength = (D - A).magnitude;
L += (chordLength + controlNetLength) / 2.0f;
}
}
first of first you should Understand the algorithm use in Bezier,
When i was coding a program by c# Which was full of graphic material I used beziers and many time I had to find a point cordinate in bezier , whic it seem imposisble in the first look. so the thing i do was to write Cubic bezier function in my costume math class which was in my project. so I will share the code with you first.
//--------------- My Costum Power Method ------------------\\
public static float FloatPowerX(float number, int power)
{
float temp = number;
for (int i = 0; i < power - 1; i++)
{
temp *= number;
}
return temp;
}
//--------------- Bezier Drawer Code Bellow ------------------\\
public static void CubicBezierDrawer(Graphics graphics, Pen pen, float[] startPointPixel, float[] firstControlPointPixel
, float[] secondControlPointPixel, float[] endPointPixel)
{
float[] px = new float[1111], py = new float[1111];
float[] x = new float[4] { startPointPixel[0], firstControlPointPixel[0], secondControlPointPixel[0], endPointPixel[0] };
float[] y = new float[4] { startPointPixel[1], firstControlPointPixel[1], secondControlPointPixel[1], endPointPixel[1] };
int i = 0;
for (float t = 0; t <= 1F; t += 0.001F)
{
px[i] = FloatPowerX((1F - t), 3) * x[0] + 3 * t * FloatPowerX((1F - t), 2) * x[1] + 3 * FloatPowerX(t, 2) * (1F - t) * x[2] + FloatPowerX(t, 3) * x[3];
py[i] = FloatPowerX((1F - t), 3) * y[0] + 3 * t * FloatPowerX((1F - t), 2) * y[1] + 3 * FloatPowerX(t, 2) * (1F - t) * y[2] + FloatPowerX(t, 3) * y[3];
graphics.DrawLine(pen, px[i - 1], py[i - 1], px[i], py[i]);
i++;
}
}
as you see above, this is the way a bezier Function work and it draw the same Bezier as Microsoft Bezier Function do( I've test it). you can make it even more accurate by incrementing array size and counter size or draw elipse instead of line& ... . All of them depend on you need and level of accuracy you need and ... .
Returning to main goal ,the Question is how to calc the lenght???
well The answer is we Have tons of point and each of them has an x coorinat and y coordinate which remember us a triangle shape & especially A RightTriabgle Shape. so if we have point p1 & p2 , we can calculate the distance of them as a RightTriangle Chord. as we remeber from our math class in school, in ABC Triangle of type RightTriangle, chord Lenght is -> Sqrt(Angle's FrontCostalLenght ^ 2 + Angle's SideCostalLeghth ^ 2);
and there is this relation betwen all points we calc the lenght betwen current point and the last point before current point(exmp p[i - 1] & p[i]) and store sum of them all in a variable. lets show it in code bellow
//--------------- My Costum Power Method ------------------\\
public static float FloatPower2(float number)
{
return number * number;
}
//--------------- My Bezier Lenght Calculator Method ------------------\\
public static float CubicBezierLenghtCalculator(float[] startPointPixel
, float[] firstControlPointPixel, float[] secondControlPointPixel, float[] endPointPixel)
{
float[] tmp = new float[2];
float lenght = 0;
float[] px = new float[1111], py = new float[1111];
float[] x = new float[4] { startPointPixel[0], firstControlPointPixel[0]
, secondControlPointPixel[0], endPointPixel[0] };
float[] y = new float[4] { startPointPixel[1], firstControlPointPixel[1]
, secondControlPointPixel[1], endPointPixel[1] };
int i = 0;
for (float t = 0; t <= 1.0; t += 0.001F)
{
px[i] = FloatPowerX((1.0F - t), 3) * x[0] + 3 * t * FloatPowerX((1.0F - t), 2) * x[1] + 3F * FloatPowerX(t, 2) * (1.0F - t) * x[2] + FloatPowerX(t, 3) * x[3];
py[i] = FloatPowerX((1.0F - t), 3) * y[0] + 3 * t * FloatPowerX((1.0F - t), 2) * y[1] + 3F * FloatPowerX(t, 2) * (1.0F - t) * y[2] + FloatPowerX(t, 3) * y[3];
if (i > 0)
{
tmp[0] = Math.Abs(px[i - 1] - px[i]);// calculating costal lenght
tmp[1] = Math.Abs(py[i - 1] - py[i]);// calculating costal lenght
lenght += (float)Math.Sqrt(FloatPower2(tmp[0]) + FloatPower2(tmp[1]));// calculating the lenght of current RightTriangle Chord & add it each time to variable
}
i++;
}
return lenght;
}
if you wish to have faster calculation just need to reduce px & py array lenght and loob count.
We also can decrease memory need by reducing px and py to array lenght to 1 or make a simple double variable but becuase of Conditional situation Happend which Increase Our Big O I didn't do that.
Hope it helped you so much. if have another question just ask.
With Best regards, Heydar - Islamic Republic of Iran.

Filling a polygon

I created this function that draws a simple polygon with n number of vertexes:
void polygon (int n)
{
double pI = 3.141592653589;
double area = min(width / 2, height / 2);
int X = 0, Y = area - 1;
double offset = Y;
int lastx, lasty;
double radius = sqrt(X * X + Y * Y);
double quadrant = atan2(Y, X);
int i;
for (i = 1; i <= n; i++)
{
lastx = X; lasty = Y;
quadrant = quadrant + pI * 2.0 / n;
X = round((double)radius * cos(quadrant));
Y = round((double)radius * sin(quadrant));
setpen((i * 255) / n, 0, 0, 0.0, 1); // r(interval) g b, a, size
moveto(offset + lastx, offset + lasty); // Moves line offset
lineto(offset + X, offset + Y); // Draws a line from offset
}
}
How can I fill it with a solid color?
I have no idea how can I modify my code in order to draw it filled.
The common approach to fill shapes is to find where the edges of the polygon cross either each x or each y coordinate. Usually, y coordinates are used, so that the filling can be done using horizontal lines. (On framebuffer devices like VGA, horizontal lines are faster than vertical lines, because they use consecutive memory/framebuffer addresses.)
In that vein,
void fill_regular_polygon(int center_x, int center_y, int vertices, int radius)
{
const double a = 2.0 * 3.14159265358979323846 / (double)vertices;
int i = 1;
int y, px, py, nx, ny;
if (vertices < 3 || radius < 1)
return;
px = 0;
py = -radius;
nx = (int)(0.5 + radius * sin(a));
ny = (int)(0.5 - radius * cos(a));
y = -radius;
while (y <= ny || ny > py) {
const int x = px + (nx - px) * (y - py) / (ny - py);
if (center_y + y >= 0 && center_y + y < height) {
if (center_x - x >= 0)
moveto(center_x - x, center_y + y);
else
moveto(0, center_y + y);
if (center_x + x < width)
lineto(center_x + x, center_y + y);
else
lineto(width - 1, center_y + y);
}
y++;
while (y > ny) {
if (nx < 0)
return;
i++;
px = nx;
py = ny;
nx = (int)(0.5 + radius * sin(a * (double)i));
ny = (int)(0.5 - radius * cos(a * (double)i));
}
}
}
Note that I only tested the above with a simple SVG generator, and compared the drawn lines to the polygon. Seems to work correctly, but use at your own risk; no guarantees.
For general shapes, use your favourite search engine to look for "polygon filling" algorithms. For example, this, this, this, and this.
There are 2 different ways to implement a solution:
Scan-line
Starting at the coordinate that is at the top (smallest y value), continue to scan down line by line (incrementing y) and see which edges intersect the line.
For convex polygons you find 2 points, (x1,y) and (x2,y). Simply draw a line between those on each scan-line.
For concave polygons this can also be a multiple of 2. Simply draw lines between each pair. After one pair, go to the next 2 coordinates. This will create a filled/unfilled/filled/unfilled pattern on that scan line which resolves to the correct overall solution.
In case you have self-intersecting polygons, you would also find coordinates that are equal to some of the polygon points, and you have to filter them out. After that, you should be in one of the cases above.
If you filtered out the polygon points during scan-lining, don't forget to draw them as well.
Flood-fill
The other option is to use flood-filling. It has to perform more work evaluating the border cases at every step per pixel, so this tends to turn out as a slower version. The idea is to pick a seed point within the polygon, and basically recursively extend up/down/left/right pixel by pixel until you hit a border.
The algorithm has to read and write the entire surface of the polygon, and does not cross self-intersection points. There can be considerable stack-buildup (for naive implementations at least) for large surfaces, and the reduced flexibility you have for the border condition is pixel-based (e.g. flooding into gaps when other things are drawn on top of the polygon). In this sense, this is not a mathematically correct solution, but it works well for many applications.
The most efficient solution is by decomposing the regular polygon in trapezoids (and one or two triangles).
By symmetry, the vertexes are vertically aligned and it is an easy matter to find the limiting abscissas (X + R cos(2πn/N) and X + R cos(2π(+1)N)).
You also have the ordinates (Y + R sin(2πn/N) and Y + R sin(2π(+1)N)) and it suffices to interpolate linearly between two vertexes by Y = Y0 + (Y1 - Y0) (X - X0) / (X1 - X0).
Filling in horizontal runs is a little more complex, as the vertices may not be aligned horizontally and there are more trapezoids.
Anyway, it seems that I / solved / this myself again, when not relying on assistance (or any attempt for it)
void polygon (int n)
{
double pI = 3.141592653589;
double area = min(width / 2, height / 2);
int X = 0, Y = area - 1;
double offset = Y;
int lastx, lasty;
while(Y-->0) {
double radius = sqrt(X * X + Y * Y);
double quadrant = atan2(Y, X);
int i;
for (i = 1; i <= n; i++)
{
lastx = X; lasty = Y;
quadrant = quadrant + pI * 2.0 / n;
X = round((double)radius * cos(quadrant));
Y = round((double)radius * sin(quadrant));
//setpen((i * 255) / n, 0, 0, 0.0, 1);
setpen(255, 0, 0, 0.0, 1); // just red
moveto(offset + lastx, offset + lasty);
lineto(offset + X, offset + Y);
} }
}
As you can see, it isn't very complex, which means it might not be the most efficient solution either.. but it is close enough.
It decrements radius and fills it by virtue of its smaller version with smaller radius.
On that way, precision plays an important role and the higher n is the less accuracy it will be filled with.

Resources