2015-11-06 4 views
1

Я расчета точки пересечения двух линий с помощью следующей функции:Точность линии пересечения с вертикальной линией

// Functions of lines as per requested: 
// f(y1) = starty1 + x * d1 
// f(y2) = starty2 + x * d2 
// x1 and y1 are the coordinates of the first point 
// x2 and y2 are the coordinates of the second point 
// d1 and d2 are the deltas of the corresponding lines 
private static double[] intersect(double x1, double y1, double d1, double x2, double y2, double d2) { 
    double starty1 = y1 - x1 * d1; 
    double starty2 = y2 - x2 * d2; 
    double rx = (starty2 - starty1)/(d1 - d2); 
    double ry = starty1 + d1 * rx; 

    tmpRes[0] = rx; 
    tmpRes[1] = ry; 

    return tmpRes; 
} 

// This is the same function, but takes 4 points to make two lines, 
// instead of two points and two deltas. 
private static double[] tmpRes = new double[2]; 
private static double[] intersect(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) { 
    double d1 = (y1 - y2)/(x1 - x2); 
    double d2 = (y3 - y4)/(x3 - x4); 
    double starty1 = y1 - x1 * d1; 
    double starty2 = y3 - x3 * d2; 
    double rx = (starty2 - starty1)/(d1 - d2); 
    double ry = starty1 + d1 * rx; 

    tmpRes[0] = rx; 
    tmpRes[1] = ry; 

    return tmpRes; 
} 

Однако, как D1 или D2 становятся больше (для вертикальных линий) результаты получают гораздо менее точны , Как я могу предотвратить это?

Для моего случая у меня есть две линии, перпендикулярные друг другу. Если линии повернуты на 45 градусов, я получаю точные результаты. Если линии на 0 или 90 градусов, я получаю неточные результаты (одна ось пересечения является правильным, а другой повсюду

Редактировать

С помощью крестовой продукта:.

private static double[] crTmp = new double[3]; 
public static double[] cross(double a, double b, double c, double a2, double b2, double c2){ 
    double newA = b*c2 - c*b2; 
    double newB = c*a2 - a*c2; 
    double newC = a*b2 - b*a2; 
    crTmp[0] = newA; 
    crTmp[1] = newB; 
    crTmp[2] = newC; 
    return crTmp; 
} 


public static double[] linesIntersect(double x1, double y1, double d1, double x2, double y2, double d2) 
{ 
    double dd1 = 1.0/d1; 
    double dd2 = 1.0/d2; 

    double a1, b1, a2, b2, c1, c2; 
    if (Math.abs(d1) < Math.abs(dd1)) { 
     a1 = d1; 
     b1 = -1.0; 
     c1 = y1 - x1 * d1; 
    } else { 
     a1 = 1.0; 
     b1 = dd1; 
     c1 = -x1 - y1 * dd1; 
    } 
    if (Math.abs(d2) < Math.abs(dd2)) { 
     a2 = d2; 
     b2 = -1.0; 
     c2 = y2 - x2 * d2; 
    } else { 
     a2 = 1.0; 
     b2 = dd2; 
     c2 = -x2 - y2 * dd2; 
    } 

    double[] v1 = {a1, b1, c1}; 
    double[] v2 = {a2, b2, c2}; 
    double[] res = cross(v1[0], v1[1], v1[2], v2[0], v2[1], v2[2]); 
    tmpRes[0] = res[0]/res[2]; 
    tmpRes[1] = res[1]/res[2]; 
    return tmpRes; 
} 
+0

пример, пожалуйста, как неясно, как результат ухудшается? Кроме того, если вы имели в виду точность десятичных точек, используйте BigDecimal. – SMA

+0

Пожалуйста, объясните, что означают значения x1, y1 и d1. –

+0

Пожалуйста, объясните, что означает «дельта соответствующих строк». Просьба указать уравнения линий в терминах x, y и d. –

ответ

2

это проще, если вы используете гомогенное обозначение:

  • C висящий ваше представление строки из y = d*x + c в

    d*x - y + c = 0 = [d -1 c] . [x y 1] 
    

    (где . означает внутренний продукт)

  • Используя эти обозначения, Вы можете написать свои строки в виде двух векторов: [d1 -1 y1] и [d2 -1 y2]

  • Возьмите крест продукт этих двух векторов, предоставив вам новый вектор:

    [d1 -1 y1] x [d2 -1 y2] = [a b c] 
    

    (Я оставлю вас, чтобы посмотреть, как вычислить декартово произведение, но это только простое умножение)

Пересечение двух точек на (a/c, b/c). Если две линии не параллельны, c будет отличным от нуля.

См: http://robotics.stanford.edu/~birch/projective/node4.html

Одним из преимуществ a*x + b*y + c = 0 формы уравнения линии является то, что вы можете представлять вертикальные линии, естественно, вы не можете представить линию x = 1 путем в виде y = m*x + c, потому что m будет бесконечность, тогда как вы можете с 1*x + 0*y - 1 = 0.

+0

Я создал новую функцию в соответствии с вашим ответом. Я считаю, что ваш последний абзац является важным, когда он сейчас идет не так. Моя новая реализация по-прежнему имеет ту же самую ошибку, что-то все еще не очень хорошо. – RobotRock