2017-07-10 108 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