2017-07-10 68 views
0

Lines and 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,我们知道1号线2号线和坐标。我只是不知道那是什么弧..

能否请你帮我计算弧点像这样?

回答

3

你有一些概念像Line/Segment,Point,Point, Circle等一样飞来飞去,而不是制造一堆难以理解的代码,让我们试着将问题分解成更容易消化的小部分。

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

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}"; 
} 

好了,我们也有或delimitted 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); 

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

+0

你一定是个好思想家,谢谢。重点是:**让我们试着将问题分解成更容易消化的小部分。** – wikiCan