2016-01-16 4 views
3

То, что я пытаюсь получить, получает координаты X, при которых определенная кривая Безье пересекает горизонтальную линию (координата y). На данный момент, у меня есть этот код:Как вычислить пересечение квадратичной кривой Безье и горизонтальной линии?

function self.getX(y) 
    if y > maxY or y < minY then 
     return 
    end 
    local a = y1 - y 
    if a == 0 then 
     return 
    end 
    local b = 2*(y2 - y1) 
    local c = (y3 - 2*y2 + y1) 

    local discriminant = (b^2 - 4*a*c) 

    if discriminant < 0 then 
     return 
    else 
     local aByTwo = 2*a 
     if discriminant == 0 then 
      local index1 = -b/aByTwo 
      if 0 < index1 and index1 < 1 then 
       return (1-index1)^2*x1+2*(1-index1)*index1*x2+index1^2*x3 
      end 
     else 
      local theSQRT = math.sqrt(discriminant) 
      local index1, index2 = (-b -theSQRT)/aByTwo, (-b +theSQRT)/aByTwo 
      if 0 < index1 and index1 < 1 then 
       if 0 < index2 and index2 < 1 then 
        return (1-index1)^2*x1+2*(1-index1)*index1*x2+index1^2*x3, (1-index2)^2*x1+2*(1-index2)*index2*x2+index2^2*x3 
       else 
        return (1-index1)^2*x1+2*(1-index1)*index1*x2+index1^2*x3 
       end 
      elseif 0 < index2 and index2 < 1 then 
       return (1-index2)^2*x1+2*(1-index2)*index2*x2+index2^2*x3 
      end 
     end 
    end  
end 

Несколько спецификаций:

  • Это Lua код.
  • local означает, что переменная является локальной для куска кода, поэтому она не влияет на функциональность кода.
  • y1, y2, y3 - координата y трех точек. То же самое относится к x1, x2, x3.
  • y - координата y горизонтальной линии, которую я вычисляю.
  • maxY - самый большой из 3-х лет.
  • miniY - самый маленький.

На данный момент этот код дает мне это:

enter image description here

  • Есть 8 кривых Безье
  • В зеленых генерируются с помощью обычного метода: (1-t)^2*x1+2*(1-t)*t*x2+t^2*x3
  • Красного точки - контрольные точки.
  • Белые линии - это то, что генерируется с использованием метода, описанного выше.
  • Прямые линии - это линии, игнорирующие их.
  • Должно быть 8 кривых, но только 4 отображаются.

Спасибо заранее,

Creator!

+0

Как не приходит ответ? Что-то не так с поста? – Creator

+0

Нет, так как тогда он вернет тот же результат для любого y. – Creator

+4

Безье имеет 'y (t) = (1-t)^2 * y1 + 2 (1-t) * t * y2 + t^2 * y3', который расширяется до' (y1-2 * y2 + y3) * т^2 + 2 (y2-y1) * T + y1'. Таким образом, вы, похоже, поменяли «a» и «c». – lhf

ответ

2

Безье кривая имеет

y(t)=(1-t)^2*y1+2(1-t)*t*y2+t^2*y 

, которая расширяется к

(y1-2*y2+y3)*t^2+2(y2-y1)*t+y1 

Вы местами a и c в квадратное уравнение a*t^2+b*t+c=0 необходимого для решения y(t)=y.

+0

Большое спасибо. PS: Как у меня глупые ошибки, которые пустые дни вашего времени! – Creator