Проведите дугу между двумя линиями. Мне нужно посчитать баллы

Линии и дуги

Я не могу найти способ нарисовать 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. Я просто не знаю, что это за дуга ..

Не могли бы вы помочь мне таким способом рассчитать точки дуги?


person wikiCan    schedule 10.07.2017    source источник


Ответы (1)


У вас есть несколько концепций, таких как _1 _ / _ 2_, Point, Circle и т. Д. Вместо того, чтобы запутывать сложный для понимания код, давайте попробуем разбить проблему на более мелкие части, которые легче усвоить.

У вас есть понятие 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}";
}

Хорошо, у нас также есть понятие сегмента или ограниченного 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;
    }
}

И наконец, что не менее важно, у нас есть понятие Circle:

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);

Разве это не намного легче читать, следить и понимать?

person InBetween    schedule 10.07.2017
comment
Вы, должно быть, хорошо мыслите, спасибо. Дело было в следующем: давайте попробуем разбить проблему на более мелкие части, которые легче усвоить. - person wikiCan; 10.07.2017