views:

115

answers:

2

I have the center point, radius, and angle to draw the pie, but the Pie function takes 4 points as input data. Does anyone have any conversion function or better explanation for this?

+2  A: 

The four points in the pie function:

  1. Upper left corner of the bounding rectangle.
  2. Lower right corner of the bounding rectangle.
  3. Point on the circle that marks the beginning of the pie.
  4. Point on the circle that marks the end of the pie (counter clockwise).

Conversion:

Centerpoint: Cx, Cy Radius: r Angle: a

Assuming your pie starts at the top.

  1. X1 = Cx-r, Y1 = Cx+r
  2. X2 = Cx+r, Y2 = Cy-r
  3. X3 = Cx, Y3 = Y1
  4. X4 = Cx + r sin(a), Y4 = Cy + r cos(a)

You might have to flip a sign somewhere, but this should do the trick.

With two different angels (a and b):

  1. X3 = Cx + r sin(a), Y3 = Cy + r cos(a)
  2. X4 = Cx + r sin(b), Y4 = Cy + r cos(b)
Gamecat
this draws a pie from zero to angle A, where does the angle B come so we have a pie from A to B?
Maysam
A: 

This is written in (old) C++, but most of it should convert to Delphi (or almost anything else) pretty easily. It also assumes the inputs are in percentages (a full circle is 100%) instead of raw angles, but (again) that should be pretty easy to deal with. It has a conversion from percentage to angle in radians, so a conversion from other units should be a pretty trivial adjustment.

class section {
    double percent;
    int color;
public:

    section(double percent_, int color_) :
        percent(percent_), color(color_) {}

    void draw(HDC destination, POINT const &center, int diameter, double &start_angle);
};

void section::draw(HDC destination, POINT const &center, int radius, double &start_angle) {

    double start_x, start_y, end_x, end_y;
    double angle, end_angle;

    int top = center.y - radius;
    int bottom = center.y + radius;
    int left = center.x - radius;
    int right = center.x + radius;

    // now we have to convert a percentage to an angle in radians.
    // there are 100 percent in a circle, and 2*PI radians in a
    // circle, so we figure this percentage of 2*PI radians.
    angle = percent / 100.0 * 2.0 * 3.1416;

    end_angle = start_angle + angle;

    // Now we have to convert these angles into rectangular
    // coordinates in the window, which depend on where we're
    // putting the chart, and how big we're making it.
    start_x = center.x + radius * cos(start_angle);
    start_y = center.y + radius * sin(start_angle);

    end_x = center.x + radius * cos(end_angle);
    end_y = center.y + radius * sin(end_angle);

    // Now we need to actually draw the pie section by selecting
    // the correct color into the DC, drawing the section, then
    // selecting the original brush back, and deleing our brush.
    HBRUSH brush = CreateSolidBrush(color);

    HBRUSH old_brush = (HBRUSH)SelectObject(destination, brush);

    Pie(destination, left, top, right, bottom, 
        (int)start_x, (int)start_y, (int)end_x, (int)end_y);

    SelectObject(destination, old_brush);
    DeleteObject(brush);

    // our sole awareness of other sections: the next section will
    // start wherever we finished.
    start_angle = end_angle;
}
Jerry Coffin