Провести бесконечную прямую через 2 точки?

Я ищу способ нарисовать бесконечную линию (линию без конца, также известную как луч) через 2 точки. Я могу нарисовать линию между двумя точками с помощью Line2D, здесь нет проблем.

Следующая бесконечная часть нуждалась в взгляде. Я простодушно подумал, давайте умножим координаты x и y из второй точки на 100 и перерисуем линию. Это работает, но только в простых случаях.

Например, вот случай, когда он создает линии под разными углами:

    g.setColor(Color.red);
    g2.setStroke(new BasicStroke(4.0f));
    g2.draw(new Line2D.Double(0, 61.632653061218946, 944, 217.25510204080692));
    g.setColor(Color.blue);
    g2.setStroke(new BasicStroke(1.0f));
    g2.draw(new Line2D.Double(0, 61.632653061218946, 944*10, 217.25510204080692*10));

Это сначала нарисует толстую красную линию, затем нарисует синюю тонкую линию.

Синяя линия имеет другой угол по сравнению с красной линией. Вот скриншот, иллюстрирующий этот эффект:

введите здесь описание изображения

Кто-нибудь знает способ исправить это или, может быть, лучший способ провести бесконечную линию через 2 точки?


person T. Akhayo    schedule 05.09.2012    source источник
comment
Умножая на 100, вы пытаетесь увеличить длину линии?   -  person juan.facorro    schedule 05.09.2012
comment
Действительно, я просто не мог подобрать подходящего слова для того, что хотел сделать. расширить было правильное слово!   -  person T. Akhayo    schedule 05.09.2012


Ответы (2)


Давайте посчитаем на секунду.

  • Первая строка (0, 61.632653061218946)-(944, 217.25510204080692). Уклон rise/run, следовательно, m = 0.16485428917329234533898305084746.
  • Вторая строка (0, 61.632653061218946)-(9440, 2172.5510204080692); m = 0.22361423382911549300847457627119.

Наклоны разные, что является еще одним способом сказать, что углы разные.

Что вам нужно сделать, так это удлинить строку. Вы не можете просто умножить обе координаты одной из точек на 10. Сначала определите x или y за пределами холста, а затем найдите другое значение.

Как ты это делаешь?

  1. Во-первых, получить уравнение для линии. Линия определяется y=m*x+b, где m — наклон, а b — точка пересечения по оси Y.

    1. We already know how to calculate the slope (rise/run = y2 - y1 / x2 - x1). We get 0.16485428917329234533898305084746
    2. Подставьте наклон и найдите b (y - m*x), вы получите 61.632653061218946. В вашем случае у вас уже есть это значение, поскольку y-перехват является y-координатой, когда x=0.
    3. Затем вы получите уравнение y = 0.16485428917329234533898305084746 * x + 61.632653061218946
  2. Теперь выберите достаточно большой x, скажем, 10000. Подставьте это значение и найдите y. Вы получаете 1710.1755447941423993898305084746.

  3. Наконец, проведите линию к этой новой точке, (0, 61.632653061218946)-(10000,1710.1755447941423993898305084746)

Отлично, теперь давайте обобщим это.

  • У нас есть две точки (x1, y1) и (x2, y2). Мы хотим найти (10000, y3).
  • Следовательно, y3 = m*x3 + b или y3 = m * 10000 + b.
  • Мы также знаем, что b = y - m * x, поэтому вставляем это и произвольно выбираем точку 1, y3 = m * 10000 + y1 - m * x1.
  • Хорошо, давайте вычтем m: y3 = m * (10000 + x1) - y1.
  • Мы знаем m = (y2 - y1) / (x2 - x1), поэтому подставляем это: y3 = ((y2 - y1) / (x2 - x1)) * (10000 + x1) - y1.

Если ваша линия не начинается с x = 0, вам нужно будет повторить этот процесс для x = 0, то есть вы должны построить линию (0, ((y2 - y1) / (x2 - x1)) * x1 - y1)-(10000,((y2 - y1) / (x2 - x1)) * (10000 + x1) - y1).

Примечание. Если x2 - x1 равно 0, у вас бесконечный наклон. Это вертикальная линия, и вам придется обрабатывать этот случай отдельно.

person lc.    schedule 05.09.2012
comment
Следите за экстремальными наклонами, так как вы имеете дело со значениями с плавающей запятой. Особенно, когда наклон бесконечности, у вас есть проблема. - person RedGreasel; 05.09.2012
comment
+1 за получение правильного ответа первым и исправление моего ответа. - person RedGreasel; 05.09.2012
comment
Спасибо за ваш обширный ответ, мне пришлось прочитать его несколько раз, чтобы полностью понять, но это потому, что я не очень хорошо разбираюсь в математике и алгоритмах. Но ваше объяснение имеет смысл даже для меня. - person T. Akhayo; 05.09.2012

Умножая вторую точку на 10, вы не сохраняете соотношение x и y. Перед умножением нужно вычесть начало координат.

g2.draw(new Line2D.Double(0, 61.632653061218946, 944*10, (217.25510204080692-61.632653061218946)*10+61.632653061218946)); должно работать.

В общем, g2.draw(new Line2D.Double(x0,y0,(x1-x0)*k+x0,(y1-y0)*k+y0) должно работать.

Математика, стоящая за этим, состоит в том, чтобы рассматривать две точки как векторы (a и b). Теперь определите третий и четвертый вектор: вектор разности (d) и вектор бесконечной конечной точки (c). Вектор разности — это просто разница между b и a; то есть d = b-a. Чтобы найти бесконечную конечную точку, нам просто нужно прибавить вектор разности, умноженный на бесконечность, к начальной точке (a). Итак, c = a + d*k, где k — сколь угодно большая константа. После замены d имеем c = a+(b-a)*k.

person RedGreasel    schedule 05.09.2012
comment
Секундочку, это только у меня так или точка не должна быть (9440,1494.591836734660794), а не (9440,1556.22448979587974)? Вы должны вычесть точку пересечения из нового значения y: (y1-y0)*k - b - person lc.; 05.09.2012
comment
Упс, я сделал ошибку. Спасибо. - person RedGreasel; 05.09.2012
comment
Это должно было быть (9440, 1617.857142857098686), а не то, что у меня было раньше (что у вас есть для x = 9440). Я подробно рассказал о том, что я делал. - person RedGreasel; 05.09.2012
comment
Спасибо за ваш ответ и за то, что нашли время, чтобы помочь мне с этой проблемой. - person T. Akhayo; 05.09.2012