Как разбить непрямую линию на четные отрезки?

У меня есть не прямая линия, определенная серией координатных точек x, y. Я мог бы без проблем нарисовать прямую линию на экране между этими точками. К сожалению, я должен нарисовать линию в отрезках равной длины.

Вот пример того, как мне нужно разбить непрямую линию с 3 точками на массив из нескольких равноотстоящих точек. (игнорируйте последнюю красную точку, это результат, когда линия не делится равномерно и также является конечной точкой)

Вот пример того, как мне нужно разбить непрямую линию с 3 точками на массив из нескольких равноотстоящих точек

Пожалуйста, обратите внимание на красную линию на "стыке". Предположим, что у меня есть прямая A->B->C с векторами AB и BC, образующими некоторый угол. В основном, линия изгибается в точке B.

Сегментация линии между точками A и B не является проблемой вплоть до точки. Но когда AB не делится равномерно по длине сегмента, мне нужно сделать что-то особенное. Мне нужно взять оставшуюся длину и считать ее одной стороной треугольника. Постоянная длина сегмента - это другая сторона треугольника, которая соединяется с сегментом BC (красная линия выше). Мне нужно знать длину от точки B до этого пересечения. С этой информацией я могу продолжить вычисление отрезков на BC.

Вот треугольник, который я пытаюсь решить (здесь и далее я буду ссылаться на переменные в том виде, в каком они изображены на этой картинке). До сих пор я разбил проблему на использование закона косинусов. c2 = a2 + b2 - 2ab * Cos (y)

Проблема в том, что я уже знаю c, это длина сегмента. Мне нужно решить для (я могу рассчитать у).

Я дошел до написания полиномиального уравнения, но теперь я застрял: a2 + b2 - 2ab * Cos (y) - c2 = 0

или Ax2 + Bx + C (A = 1, B = -2b * Cos (y), C = b2 - c2, x = a)

Это даже правильный подход? Что мне делать дальше? Мне нужно реализовать это в Actionscript.

РЕДАКТИРОВАТЬ: Duh, я бы использовал квадратную формулу. Итак, я теперь получаю:

a = b * Cos (y) +/- SqrRoot (c2 - b2 * Sin (y)2)

Теперь, как поместить это в код...

1 ответ

Решение

Вот как я это решил. B и C такие же, как вы их определили, я называю точку A концом последнего полного сегмента в первой строке. (последняя точка перед изгибом) Если вы нарисуете круг с центром в точке A и радиусом = длиной вашего сегмента, то в том месте, где этот круг пересекает линию BC, это конечная точка (назовите ее D) линии от A, которая обрезает ваш угол, Чтобы найти эту точку, я нашел полезную вспомогательную функцию. Она не очень длинная, и для простоты я просто вставляю ее сюда.

/*---------------------------------------------------------------------------
Returns an Object with the following properties:
    enter           -Intersection Point entering the circle.
    exit            -Intersection Point exiting the circle.
    inside          -Boolean indicating if the points of the line are inside the circle.
    tangent     -Boolean indicating if line intersect at one point of the circle.
    intersects      -Boolean indicating if there is an intersection of the points and the circle.

If both "enter" and "exit" are null, or "intersects" == false, it indicates there is no intersection.

This is a customization of the intersectCircleLine Javascript function found here:

http://www.kevlindev.com/gui/index.htm

----------------------------------------------------------------------------*/
function lineIntersectCircle(A : Point, B : Point, C : Point, r : Number = 1):Object {
    var result : Object = new Object ();
    result.inside = false;
    result.tangent = false;
    result.intersects = false;
    result.enter=null;
    result.exit=null;
    var a : Number = (B.x - A.x) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y);
    var b : Number = 2 * ((B.x - A.x) * (A.x - C.x) +(B.y - A.y) * (A.y - C.y));
    var cc : Number = C.x * C.x + C.y * C.y + A.x * A.x + A.y * A.y - 2 * (C.x * A.x + C.y * A.y) - r * r;
    var deter : Number = b * b - 4 * a * cc;
    if (deter <= 0 ) {
        result.inside = false;
    } else {
        var e : Number = Math.sqrt (deter);
        var u1 : Number = ( - b + e ) / (2 * a );
        var u2 : Number = ( - b - e ) / (2 * a );
        if ((u1 < 0 || u1 > 1) && (u2 < 0 || u2 > 1)) {
            if ((u1 < 0 && u2 < 0) || (u1 > 1 && u2 > 1)) {
                result.inside = false;
            } else {
                result.inside = true;
            }
        } else {
            if (0 <= u2 && u2 <= 1) {
                result.enter=Point.interpolate (A, B, 1 - u2);
            }
            if (0 <= u1 && u1 <= 1) {
                result.exit=Point.interpolate (A, B, 1 - u1);
            }
            result.intersects = true;
            if (result.exit != null && result.enter != null && result.exit.equals (result.enter)) {
                result.tangent = true;
            }
        }
    }
    return result;
}

Это функция, которая возвращает объект с несколькими свойствами, поэтому реализовать его в своем коде очень просто. Вам нужно пройти три точки и радиус. Первые две точки - это просто B и C, как вы их определили выше, и точка A, как я объяснил в начале. Радиус, опять же, длина вашего сегмента.

//create an object
var myObject:Object = lineIntersectCircle(pointB, pointC, pointA, segmentLength);

Это оно! Координаты точки D (см. Выше): (myObject.exit.x, myObject.exit.y)

Другие вопросы по тегам