Как GraphicsPath.AddArc использует параметры startAngle и sweepAngle? - PullRequest
5 голосов
/ 21 августа 2009

Я пытаюсь использовать System.Drawing.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 text

Ответы [ 2 ]

4 голосов
/ 02 ноября 2016

enter image description here Меня запутало, как работает GraphicsPath.AddArc, и я не смог найти приличных диаграмм, поэтому я нарисовал одну. На всякий случай, если кто-то еще страдал так же! http://imgur.com/lNBewKZ

3 голосов
/ 21 августа 2009

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);

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

...