Проблема в том, что используемое преобразование не отображает прямые линии на прямые.Скорее прямые, как правило, идут к параболам.Вы можете видеть это на примерах изображений, где более или менее прямая главная дорога, идущая сверху вниз в 2D-виде, преобразуется в изогнутую дорогу в 2.5D-виде.То же самое вы увидите для линий, которые «сходят с ума» в вашем примере, если разбить их на более короткие сегменты.
Математически вы можете увидеть, что происходит, вернувшись к преобразованию, в котором вы находитесь.используя:
x_ = (x - w/2)*(t1+(y/h)*(t2-t1)) + w/2
y_ = y
Если мы выражаем прямую линию как x = ay+b
, то точка (ay+b,y)
на этой линии отображается на (ay+b - w/2)*(t1+(y/h)*(t2-t1)) + w/2,y)
.Это выражение выглядит сложным, но вы можете видеть, что оно оценивается как (c*y^2+d*y+e,y)
для подходящих значений c,d,e
, что является параболой.
Так что вам лучше всего отказаться от этого преобразования и переключиться на перспективное преобразование .
В своем первоначальном вопросе вы упомянули, что неаффинное преобразование визуализированного изображения было слишком медленным.Кажется, вы перешли на преобразование линий перед их рендерингом, и это достаточно быстро.Единственное, что вам нужно сделать сейчас, это изменить преобразование.
Вот предлагаемое преобразование.Это пара шагов, и ваши 2D (x, y) координаты переводятся в некоторые 2.5D (u, v) координаты.Я предполагаю, что вы используете C #.
t = 0.3 // tilt angle - try different values
X = x - w/2 ;
Y = y - h/2 ;
a = h/(h + Y*Math.Sin(t)) ;
u = a*X + w/2 ;
v = a*Y*Math.Cos(t) + h/2 ;
Здесь есть параметр t
, который определяет величину наклона, выраженную в радианах.Я бы посоветовал играть со значением где-то около 0,3, плюс или минус.
Я работал с карандашом и бумагой, но не запускал его, поэтому дайте мне знать, если это не сработает.Всегда возможно, что произошла ошибка транскрипции.
Обновление: Вы хотите избежать рисования любого объекта (линии, многоугольника и т. д.), который имеет точку (x,y)
, такую, что a
не является положительным.Более того, чтобы избежать переполнения, вам следует избегать рисования, когда a<epsilon
, где epsilon
- это небольшое положительное значение, например 0,05 или 0,1.