【问题标题】:Draw arc between two lines. I need to calculate points在两条线之间画圆弧。我需要计算积分
【发布时间】:2017-07-10 10:10:43
【问题描述】:

我找不到在两条线之间绘制 ARC 的方法。我的约束是:我必须计算这个 Arc 笔划点。因为我使用的是 InkCanvas,而且我必须逐点绘制这个弧线,所以我不能将任何对象放在屏幕或画布上。所以我知道我可以用 PATH 对象绘制任何弧并使用 ArcSegment。使用这种方法是的,我可以绘制弧线,但它不是画布上的笔画点。因此,我无法删除或保存它。 无论如何,我需要逐点计算这个拱门。

我有像这样在画布上绘制圆圈的代码:

Stroke GetCircleStroke(int centerX, int centerY, int radiusX, int radiusY,double angletoDraw=2.0)
        {
            StylusPointCollection strokePoints = new StylusPointCollection();

            int numTotalSteps = 180;

            for (int i = 0; i <= numTotalSteps; i++)
            {
                double angle = angletoDraw * Math.PI * (double)i / (double)numTotalSteps;
                StylusPoint sp = new StylusPoint();
                //compute x and y points
                sp.X = centerX + Math.Cos(angle) * radiusX;
                sp.Y = centerY - Math.Sin(angle) * radiusY;

                //add to the collection
                strokePoints.Add(sp);
            }

            Stroke newStroke = new Stroke(strokePoints);
            return newStroke;

        }

我可以很容易地画圆,但我找不到画圆弧的方法:(

我们知道中心点 X,Y 并且我们知道 Line1 和 Line2 坐标。我只是不知道那是什么弧..

你能帮我这样计算弧点吗?

【问题讨论】:

    标签: c# wpf canvas mat inkcanvas


    【解决方案1】:

    您有一些概念飞来飞去,例如Line/SegmentPointCircle 等。我们不要把难以理解的代码弄得一团糟,而是尝试将问题分解成更小的部分更容易消化。

    你有一个Point的概念,好的,让我们实现一个:

    public struct Point2D //omitted equality logic
    {
        public double X { get; }
        public double Y { get; }
    
        public Point2D(double x, double y)
        {
            X = x;
            Y = y;
        }
    
        public override string ToString() => $"{X:N3}; {Y:N3}";
    }
    

    好的,我们还有一个 Segment 的概念或分隔的Line

    public struct Segment2D
    {
        public Point2D Start { get; }
        public Point2D End { get; }
        public double Argument => Math.Atan2(End.Y - Start.Y , End.X - Start.X);
    
        public Segment2D(Point2D start, Point2D end)
        {
            Start = start;
            End = end;
        }
    }
    

    最后但并非最不重要的是,我们有的概念:

    public struct Circle2D
    {
        private const double FullCircleAngle = 2 * Math.PI;
        public Point2D Center { get; }
        public double Radius { get; }
    
        public Circle2D(Point2D center, double radius)
        {
            if (radius <= 0)
                throw new ArgumentOutOfRangeException(nameof(radius));
    
            Center = center;
            Radius = radius;
        }
    
        public IEnumerable<Point2D> GetPointsOfArch(int numberOfPoints, double startAngle, double endAngle)
        {
            double normalizedEndAngle;
    
            if (startAngle < endAngle)
            {
                normalizedEndAngle = endAngle;
            }
            else
            {
                normalizedEndAngle = endAngle + FullCircleAngle;
            }
    
            var angleRange = normalizedEndAngle - startAngle;
            angleRange = angleRange > FullCircleAngle ? FullCircleAngle : angleRange;
            var step = angleRange / numberOfPoints;
            var currentAngle = startAngle;
    
            while (currentAngle <= normalizedEndAngle)
            {
                var x = Center.X + Radius * Math.Cos(currentAngle);
                var y = Center.Y + Radius * Math.Sin(currentAngle);
                yield return new Point2D(x, y);
                currentAngle += step;
            }
        }
    
        public IEnumerable<Point2D> GetPoints(int numberOfPoints)
            => GetPointsOfArch(numberOfPoints, 0, FullCircleAngle);
    }
    

    研究GetPointsOfArch的实现,应该不难理解。

    现在,要解决您的问题,您可以:

    var myCircle = new Circle2D(new Point2D(centerX, centerY), radius);
    var line1 = ....
    var line2 = ....
    var archPoints = myCircle.GetPointsOfArch(number, line2.Argument, line1.Argument);
    

    阅读、遵循和理解不是更容易吗?

    【讨论】:

    • 你一定是个善于思考的人,谢谢。重点是:让我们尝试将问题分解成更容易消化的小部分。
    猜你喜欢
    • 1970-01-01
    • 2017-10-12
    • 2017-02-26
    • 2014-01-02
    • 2016-08-25
    • 1970-01-01
    相关资源
    最近更新 更多