Skip to main content
Participant
August 8, 2008
Question

question about curveTo

  • August 8, 2008
  • 1 reply
  • 653 views
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 has been closed for replies.

1 reply

kglad
Community Expert
Community Expert
August 9, 2008
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))
Inspiring
April 20, 2023

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?

kglad
Community Expert
Community Expert
April 20, 2023

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.