Как работает GraphicsPath.AddArc использует параметры startAngle и sweepAngle?


Я пытаюсь использовать систему.Рисование.Drawing2D.GraphicsPath.AddArc нарисует дугу эллипса, начинающуюся с 0 градусов и расширяющуюся до 135 градусов.

Проблема, с которой я сталкиваюсь, заключается в том, что для эллипса нарисованная дуга не совпадает с тем, что я ожидал бы.

Например, следующий код генерирует изображение ниже. Зеленые круги находятся там, где я ожидал бы, что конечные точки дуги будут использовать формулу для точки вдоль эллипса. Моя формула работает для кругов но не для эллипсов.

Имеет ли это какое-то отношение к полярным и декартовым координатам?
    private PointF GetPointOnEllipse(RectangleF bounds, float angleInDegrees)
    {
        float a = bounds.Width / 2.0F;
        float b = bounds.Height / 2.0F;

        float angleInRadians = (float)(Math.PI * angleInDegrees / 180.0F);

        float x = (float)(( bounds.X + a ) + a * Math.Cos(angleInRadians));
        float y = (float)(( bounds.Y + b ) + b * Math.Sin(angleInRadians));

        return new PointF(x, y);
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        Rectangle circleBounds = new Rectangle(250, 100, 500, 500);
        e.Graphics.DrawRectangle(Pens.Red, circleBounds);

        System.Drawing.Drawing2D.GraphicsPath circularPath = new System.Drawing.Drawing2D.GraphicsPath();
        circularPath.AddArc(circleBounds, 0.0F, 135.0F);
        e.Graphics.DrawPath(Pens.Red, circularPath);

        PointF circlePoint = GetPointOnEllipse(circleBounds, 135.0F);
        e.Graphics.DrawEllipse(Pens.Green, new RectangleF(circlePoint.X - 5, circlePoint.Y - 5, 10, 10));

        Rectangle ellipseBounds = new Rectangle(50, 100, 900, 500);
        e.Graphics.DrawRectangle(Pens.Blue, ellipseBounds);

        System.Drawing.Drawing2D.GraphicsPath ellipticalPath = new System.Drawing.Drawing2D.GraphicsPath();
        ellipticalPath.AddArc(ellipseBounds, 0.0F, 135.0F);
        e.Graphics.DrawPath(Pens.Blue, ellipticalPath);

        PointF ellipsePoint = GetPointOnEllipse(ellipseBounds, 135.0F);
        e.Graphics.DrawEllipse(Pens.Green, new RectangleF(ellipsePoint.X - 5, ellipsePoint.Y - 5, 10, 10));
    }

текст Alt

2 5

2 ответа:

GraphicsPath.AddArc делает именно то, что вы просите его сделать-это дуга до линии, выступающей из центра эллипса, под точным углом 135 градусов по часовой стрелке от оси X.

К сожалению, это не помогает, когда вы используете угол как прямую пропорцию среза круговой диаграммы, который вы хотите нарисовать. Чтобы узнать угол B, который нужно использовать с AddArc, учитывая угол A, который работает на окружности, в радианах, используйте:
B = Math.Atan2(sin(A) * height / width, cos(A))

Где ширина и высота являются те, что из эллипса.

В вашем примере кода попробуйте добавить следующее В конце Form1_Paint:

ellipticalPath = new System.Drawing.Drawing2D.GraphicsPath();
ellipticalPath.AddArc(
    ellipseBounds,
    0.0F,
    (float) (180.0 / Math.PI * Math.Atan2(
        Math.Sin(135.0 * Math.PI / 180.0) * ellipseBounds.Height / ellipseBounds.Width,
        Math.Cos(135.0 * Math.PI / 180.0))));
e.Graphics.DrawPath(Pens.Black, ellipticalPath);

Результат должен выглядеть следующим образом: alt текст http://img216.imageshack.us/img216/1905/arcs.png

Введите описание изображения здесья начал путаться в том, как GraphicsPath.AddArc работал , и я не смог найти ни одной приличной диаграммы, поэтому я нарисовал одну. Просто на случай, если кто-то еще страдал так же! http://imgur.com/lNBewKZ