2017-07-10 5 views
0

Lines and arc2本の線の間に円弧を描きます。私は、私は2つのラインの間に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/SegmentPointCircleなどのようないくつかの概念があります。コードを理解するのが難しいのではなく、簡単に問題を小さな部分に分解してみましょう。

あなたはポイントの概念を持っているが、OK、1を実装することができます:

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

[OK]を、我々はまた、セグメントまたは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

関連する問題