Skip to main content
Participant
Aug 8, 2008 11:55 PM UTC
Question

question about curveTo

Hi all,

I have a question about the curveTo function. I'm trying to make a simple pie-chart like application (except all the slices are always equal size). I know how to do the lines, but here's the issue: Each slice needs to be filled with a different color. At the moment, I just do a beginFill at the start of each slice, draw a line on its outside, a curve to the end of the next slices line, and then a line back to the middle, making a slice of a given color.

The problem is that the curveTo function doesn't make a decent circle. I'm not great with trig, so trying to figure this out is driving me nuts. Here's some code so you can see what I mean:

function polar_to_cart(r,t) {
var x = r * Math.cos(t);
var y = r * Math.sin(t);
return new Array(x,y);
}

function deg_to_rad(deg) {
return deg * (Math.PI / 180);
}

// The following function will draw a basic "pin wheel" diagram.
// It's just a test.
function pinwheel(slices:Number, radius:Number) {
var deg = 360 / slices; //How many degrees to separate each slice

// Create a new movie clip
var wheel = new MovieClip();
wheel.graphics.lineStyle(1,0x990000,0.75);

var coords:Array = new Array(2);
var t:Number;
for(var i = 0; i < slices; i++) {
//Do a slice fill
wheel.graphics.beginFill(Math.random()*0xFFFFFF);
t = deg * i;
t = deg_to_rad(t);
coords = polar_to_cart(radius,t);
coords[0] += radius;
coords[1] += radius;
wheel.graphics.moveTo(radius, radius);
wheel.graphics.lineTo(coords[0],coords[1]);

//Do a curve from this point, to the next, passing through a point splitting their angle
t = deg_to_rad((deg * (i + 1)) - (deg / 2));
var half_point = polar_to_cart(radius,t);
var cx = half_point[0] + radius;
var cy = half_point[1] + radius;
t = deg_to_rad(deg * (i + 1));
var next_point = polar_to_cart(radius,t);
var nx = next_point[0] + radius;
var ny = next_point[1] + radius;
wheel.graphics.curveTo(cx,cy,nx,ny);

//And now we trace the last line.
wheel.graphics.lineTo(radius,radius);

wheel.graphics.endFill();
}

//Now, we draw the circle all the way around.
//wheel.graphics.drawCircle(radius,radius,radius);
addChild(wheel);
}

pinwheel(16,200);


If you try even fewer slices, the problem that I am running into gets even more extreme. Does anyone have any thoughts on how I could solve that?

Thanks,
-Thomas

ps,
please ignore crappy coding standards. It's been a long day, and its a proof of concept...
This topic is closed to new replies. Start a new post to keep the conversation going.

5 replies

kglad
Community Expert
Community Expert
Aug 9, 2008 12:31 AM UTC
don't use the curveTo() if you want a pixel-perfect circular arc. use the lineTo() and use your trig to draw the arc:

lineTo(radius*Math.cos(angle),radius*Math.sin(angle))
Translate
Inspiring
Apr 20, 2023 6:37 PM UTC

Hi, I'm also attempting, 15 years later, to draw a pie chart, and also having problems with curveTo. I'm not sure if the current curveTo is improved or not, but when I try to connect the sides of the slice with an arc, from the start angle to the end angle, with slices defined as an array of percentages totalling 100, I get a concave curve rather than an arc of the specified radius with this code:

 

var startAngle:Number = -90;

for (var i:int = 0; i < slices.length; i++) {
var sliceAngle:Number = slices[i] / 100 * 360;
var endAngle:Number = startAngle + sliceAngle;
var startRadians:Number = startAngle * Math.PI / 180;
var endRadians:Number = endAngle * Math.PI / 180;

pieChart.graphics.beginFill(getRandomColor());
pieChart.graphics.moveTo(originX, originY);
pieChart.graphics.lineTo(originX + Math.cos(startRadians) * radius, originY + Math.sin(startRadians) * radius);


pieChart.graphics.curveTo(originX, originY, originX + Math.cos(endRadians) * radius, originY + Math.sin(endRadians) * radius);


pieChart.graphics.lineTo(originX, originY);
pieChart.graphics.endFill();

 

startAngle = endAngle;
}

 

Do I not have the correct argument for curveTo?

Translate
kglad
Community Expert
Community Expert
Apr 20, 2023 8:43 PM UTC

your control points are originX,originY so that's probably exactly what you do not want.  though again, using lineTo is much easier to control.

Translate