wpf 两点和半径之间的弧段

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21957779/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 10:59:26  来源:igfitidea点击:

Arc Segment between two points and a radius

c#wpfgeometry

提问by Eggi

I am trying to paint an arc segment using WPF, but I somehow cannot figure out how to do this using the ArcSegment-Element.

我正在尝试使用 WPF 绘制弧段,但不知何故我无法弄清楚如何使用 ArcSegment-Element 执行此操作。

I have two points of the arc given (P1 and P2) and I also have the center of the circle and the radius.

我有给定的弧的两个点(P1 和 P2),我还有圆心和半径。

enter image description here

在此处输入图片说明

采纳答案by Clemens

Create a PathFigure with P1 as StartPointand an ArcSegment with P2 as Pointand a quadratic Sizethat contains the radius.

创建一个 P1 为的 PathFigureStartPoint和一个 P2 为的 ArcSegmentPoint以及一个Size包含半径的二次方。

Example: P1 = (150,100), P2 = (50,50), Radius = 100, i.e. Size=(100,100):

例子:P1 = (150,100), P2 = (50,50), Radius = 100, 即Size=(100,100):

<Path Stroke="Black">
    <Path.Data>
        <PathGeometry>
            <PathFigure StartPoint="150,100">
                <ArcSegment Size="100,100" Point="50,50"/>
            </PathFigure>
        </PathGeometry>
    </Path.Data>
</Path>

or shorter:

或更短:

<Path Stroke="Black" Data="M150,100 A100,100 0 0 0 50,50"/>

回答by johnml1135

I know this is a little old, but here goes a code version for a center and two angles - can be adapted to start and end points easily:

我知道这有点旧,但这里有一个中心和两个角度的代码版本 - 可以轻松适应起点和终点:

Outline:

大纲:

  • Make a path and set the "top left" to 0,0 (You can still have center be negative if you want - this is just for path reference)
  • Set up the boiler plate PathGeo and PathFigure (these are building blocks of the multi-segment path in Word etc.)
  • Do angle checking
  • If it is > 180 deg (pi radians), call it a "large angle"
  • Find begining and end points and set them
  • Based upon the math, it is a clockwise rotation (remember that positive Y is down, positive X is right)
  • Set to canvas

    public void DrawArc(ref Path arc_path, Vector center, double radius, double start_angle, double end_angle, Canvas canvas)
    {
        arc_path = new Path();
        arc_path.Stroke = Brushes.Black;
        arc_path.StrokeThickness = 2;
        Canvas.SetLeft(arc_path, 0);
        Canvas.SetTop(arc_path, 0);
    
        start_angle = ((start_angle % (Math.PI * 2)) + Math.PI * 2) % (Math.PI * 2);
        end_angle = ((end_angle % (Math.PI * 2)) + Math.PI * 2) % (Math.PI * 2);
        if(end_angle < start_angle){
            double temp_angle = end_angle;
            end_angle = start_angle;
            start_angle = temp_angle;
        }
        double angle_diff = end_angle - start_angle;
        PathGeometry pathGeometry = new PathGeometry();
        PathFigure pathFigure = new PathFigure();
        ArcSegment arcSegment = new ArcSegment();
        arcSegment.IsLargeArc = angle_diff >= Math.PI;
        //Set start of arc
        pathFigure.StartPoint = new Point(center.X + radius * Math.Cos(start_angle), center.Y + radius * Math.Sin(start_angle));
        //set end point of arc.
        arcSegment.Point = new Point(center.X + radius * Math.Cos(end_angle), center.Y + radius * Math.Sin(end_angle));
        arcSegment.Size = new Size(radius, radius);
        arcSegment.SweepDirection = SweepDirection.Clockwise;
    
        pathFigure.Segments.Add(arcSegment);
        pathGeometry.Figures.Add(pathFigure);
        arc_path.Data = pathGeometry;
        canvas.Children.Add(arc_path);
    }
    
  • 制作一条路径并将“左上角”设置为 0,0(如果需要,您仍然可以将中心设为负数 - 这仅用于路径参考)
  • 设置样板 PathGeo 和 PathFigure(这些是 Word 等中多段路径的构建块)
  • 做角度检查
  • 如果大于 180 度(pi 弧度),则称其为“大角度”
  • 找到起点和终点并设置它们
  • 根据数学计算,它是顺时针旋转(记住正 Y 是向下,正 X 是右)
  • 设置为画布

    public void DrawArc(ref Path arc_path, Vector center, double radius, double start_angle, double end_angle, Canvas canvas)
    {
        arc_path = new Path();
        arc_path.Stroke = Brushes.Black;
        arc_path.StrokeThickness = 2;
        Canvas.SetLeft(arc_path, 0);
        Canvas.SetTop(arc_path, 0);
    
        start_angle = ((start_angle % (Math.PI * 2)) + Math.PI * 2) % (Math.PI * 2);
        end_angle = ((end_angle % (Math.PI * 2)) + Math.PI * 2) % (Math.PI * 2);
        if(end_angle < start_angle){
            double temp_angle = end_angle;
            end_angle = start_angle;
            start_angle = temp_angle;
        }
        double angle_diff = end_angle - start_angle;
        PathGeometry pathGeometry = new PathGeometry();
        PathFigure pathFigure = new PathFigure();
        ArcSegment arcSegment = new ArcSegment();
        arcSegment.IsLargeArc = angle_diff >= Math.PI;
        //Set start of arc
        pathFigure.StartPoint = new Point(center.X + radius * Math.Cos(start_angle), center.Y + radius * Math.Sin(start_angle));
        //set end point of arc.
        arcSegment.Point = new Point(center.X + radius * Math.Cos(end_angle), center.Y + radius * Math.Sin(end_angle));
        arcSegment.Size = new Size(radius, radius);
        arcSegment.SweepDirection = SweepDirection.Clockwise;
    
        pathFigure.Segments.Add(arcSegment);
        pathGeometry.Figures.Add(pathFigure);
        arc_path.Data = pathGeometry;
        canvas.Children.Add(arc_path);
    }