Проблема с высоты птичьего полета или 2.5D рендеринга карты - PullRequest
1 голос
/ 05 сентября 2010

Я разрабатываю пошаговое навигационное программное обеспечение и использую следующее решение, чтобы превратить мои линии дорог в 2.5D или 3D View

Рисование 2.5D или 3D-карты с C # из линий

Однако вышеприведенное решение вполне подходит для линий в пределах порта просмотра, который равен 0 высоту или x> ширину, и тогда вышеуказанное решение сошло с ума. Может ли кто-нибудь помочь мне понять, как решить проблему?

vvvv С 3D-алгоритмом vvvv

alt text

.

vvvv Без 3D алгоритма vvvv

alt text

Обновление :: После использования этого кода

double x = p->x();
double y = p->y();

double t = -0.5;
x = x - w / 2;
y = y - h / 2;
double a = h / (h + y* sin(t));
double u = a * x + w / 2;
double v = a * y * cos(t) + h / 2;

p->setX(u);
p->setY(v);
return p;

Карта стала похожей на следующую alt text

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

Ответы [ 2 ]

4 голосов
/ 08 сентября 2010

Проблема в том, что используемое преобразование не отображает прямые линии на прямые.Скорее прямые, как правило, идут к параболам.Вы можете видеть это на примерах изображений, где более или менее прямая главная дорога, идущая сверху вниз в 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.

0 голосов
/ 08 сентября 2010

Проблема с уравнением состоит в том, что оно позволяет проецируемому значению x пересечь среднюю линию (w/2).Это нежелательно при попытке смоделировать перспективное преобразование, поскольку линии должны приближаться, но не пересекать точку схода.Кроме того, из-за способа написания уравнения это пересечение происходит перед камерой, а не позади, что приводит к ненужным артефактам.Попробуйте что-то вроде этого:

halfW = w/2
dx = (x - halfW)
dy = (h - y) // y increases downwards
// tune these constants to taste.
top = 1.25
bottom = 0.75
lowerBound = 0.1 // Avoids divide by zero and perspective lines crossing midline
x_ = (dx / max(lowerBound, (bottom + ((dy / h) * (top - bottom))))) + w/2
...