Как GraphicsPath.AddArc использует параметры startAngle и SweepAngle?
-
19-09-2019 - |
Вопрос
Я пытаюсь использовать 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));
}
Решение
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
Другие советы
Меня смутило, как работает GraphicsPath.AddArc, и я не смог найти достойных диаграмм, поэтому нарисовал одну.На всякий случай, если кто-то еще страдал так же! http://imgur.com/lNBewKZ