LINUX.ORG.RU

конвертирование координат из 3D в 2D

 , ,


0

1

В трехмерном пространстве есть плоскость заданная уравнением Ax + By + Cz +D = 0

На ней лежат две точки T1 (x,y,z) и T2 (x,y,z). Середина отрезка образованная этими точками должна стать началом новой двумерной системы координат (0,0), а прямая, проходящая через эти точки - осью ОХ.

Пытаюсь реализовать функцию конвертирования координат любой точки из трехмерного пространства в координаты в новой двумерной системе координат.

Если у кого есть готовые примеры было бы круто. Вручную фигачить направляющие косинусы не айс.


Строишь трехмерную систему координат, привязанную к твом точкам, переводишь координаты в нее и игнорируешь z.

grondek
()

не надо вручную. Это аффинное преобразование. Надо просто один раз вычислить матрицу проекции.

dikiy ★★☆☆☆
()

Если подробнее, то пусть [latex]TX=\frac {T1-T2}{|T1-T2|}[/latex], А TY - перпендикулярный ему лежащий в плоскости единичный вектор.

тогда матрица будет [latex]A:=\begin{bmatrix}TX_x & TX_y & TX_z\\ TY_x & TY_y & TY_z \end{bmatrix}[/latex] вектор переноса будет [latex]d:=(T1-T2)/2[/latex] и итоговое преобразование координат по формуле: [latex]A(v-d)[/latex]

dikiy ★★☆☆☆
()
Последнее исправление: dikiy (всего исправлений: 3)

если не можешь прочесть latex, то поставь скрипт для грязной макаки из профиля Эдички.

dikiy ★★☆☆☆
()
Ответ на: комментарий от dikiy

Кстати, странно почему на лоре до сих пор скрипт не добавили в движок. Дискриминация латеха.

invy ★★★★★
()

ключевые слова для гугления: матричные преобразования и проекции, основы трёхмерной графики, проективная геометрия, линейная алгебра.

начать можно отсюда: http://habrahabr.ru/post/126269/

Deleted
()

Пытаюсь реализовать функцию конвертирования координат любой точки из трехмерного пространства в координаты в новой двумерной системе координат.

А третье измерение куда должно деться?

Manhunt ★★★★★
()
Ответ на: комментарий от Manhunt

Проекция же, ты же как-то видишь на 2ух мерном мониторе 3ех мерное изображение.

Dantix ★★
()
Ответ на: комментарий от Eddy_Em

Нет нет. В случае с проекцией я получаю искаженное изображение. Окружность на этой плоскости может стать эллипсом. А мне нужно в трехмерной системе координат на плоскости построить двумерную. Тогда сохранятся все пропорции/расстояния.

JANB
() автор топика

Нарисовал - http://itmages.ru/image/view/1923894/6dcd43f6

Сиреневая - плоскость которую я имею и знаю её уравнение. На ней лежит фигура.

Также на этой плоскости лежит система соординат X1-O1-Y1

Я знаю координаты точек фигуры в системе O-X-Y-Z Мне нужно получить координаты точек фигуры в X1-O1-Y1

sudo cast Eddy_Em dikiy Manhunt Dantix

JANB
() автор топика
Ответ на: комментарий от Eddy_Em

Я так понимаю ему просто нужно строить изображение в системе координат повернутой относительно текущей на некоторые углы.

anonymous
()
Ответ на: комментарий от JANB

Едрена вошь, это ж вообще элементарно! Тебе dikiy в самом начале про аффинные преобразования и говорил! Смещаешь вектор на новую систему координат, затем поворачиваешь. Если матрицу преобразования взять трехмерной, то реализуется это одной-единственной матрицей.

// а вдруг фигура не совсем на плоскости будет?

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от anonymous

Да. Плюс смещение, но это фигня.

JANB
() автор топика
Vec3 Sub(Vec3 Q, Vec3 R)
{
return Vec3(Q.x-R.x, Q.y-R.y, Q.z-R.z);
}

Vec3 Middle(Vec3 Q, Vec3 R)
{
return Vec3((Q.x+R.x)/2, (Q.y+R.y)/2, (Q.z+R.z)/2);
}

Vec3 VMul(Vec3 Q, Vec3 R)
{
return Vec3(Q.y*R.z-Q.z*R.y,Q.z*R.x-Q.x*R.z,Q.x*R.y-Q.y*R.x);
}

Scalar SMul(Vec3 Q, Vec3 R)
{
return Q.x*R.x + Q.y*R.y + Q.z*R.z;
}

Vec2 Transform(Plane3 plane, Vec3 T1, Vec3 T2, Vec3 P)
{
Vec3 N(plane.A, plane.B, plane.C);
Vec3 U(Sub(T2,T1));
Vec3 V(VMul(U,N));
Vec3 O(Middle(T2,T1));
Vec3 OP(Sub(P,O));
return Vec2( SMul(OP,U) / sqrt(SMul(U,U)), SMul(OP,V) / sqrt(SMul(V,V)));
}
Manhunt ★★★★★
()
Ответ на: комментарий от Eddy_Em

а вдруг фигура не совсем на плоскости будет?

Я там ставлю только пару точек, их проверить легко. Далее программа по этим точкам (уже в двумерном пространстве) и большому радиусу интерполирует теоретический эллипс ломаной - массив точек(x,y). А эти точки я назад перевожу в 3D (x,y,z)

JANB
() автор топика
Ответ на: комментарий от JANB

Пример неудачный. И так ясно, что ZX перейдёт сама в себя, а другие стороны перейдёт в оси. В принципе можно уже от этого плясать.

А в обще случае да - нужны всякие матрицы (так быстрее).

anonymous
()
  • Определяешь координаты нового центра тяжести: [latex]\vec{c}= (\vec{T_1}+\vec{T_2})/2)[/latex]
  • Составляешь элементарное уравнение: [latex]\vec{c}+\vec{v'}=\vec{v}[/latex], где v — вектор на 3D, v' — вектор на 2D (но трехмерный), откуда [latex]\vec{v'} = \vec{v}-\vec{c}[/latex]
  • А теперь просто находишь проекции этого вектора на координатные оси (они тоже у тебя 3D-вектора, как их найти, думаю, нагуглишь): [latex]x = \vec{v'}\cdot\vec{\imath}[/latex], [latex]y = \vec{v'}\cdot\vec{\jmath}[/latex]

Понятно, что первый пункт вычисляется только один раз.

По сути же это — то же самое, что писал dikiy, но без непонятных тебе матриц.

Eddy_Em ☆☆☆☆☆
()

Вычислить базисные векторы,

X = (T2-T1)/2
Y = [A,B,C] cross X

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

amaora ★★
()
Ответ на: комментарий от JANB
  • P - это точка, координаты которой надо преобразовать
  • N - это вектор нормали к твоей плоскости;
  • U - это вектор вдоль твоей прямой (он задает первую новую ось координат);
  • V - это вектор, перпендикулярный U, и притом лежащий в плоскости (он задаёт вторую новую ось координат);
  • O - это точка, лежащая в новом начале координат.

Ну а дальше всё просто: строим проекции вектора OP на единичные вектора, направленные вдоль первой и вдоль второй новых осей координат.

Manhunt ★★★★★
()
Ответ на: комментарий от Eddy_Em

Да я не боюсь матриц =)

Спасибо. Всё понятно!

JANB
() автор топика
Ответ на: комментарий от Manhunt

Я полностью разобрался, всё построил. Круто, работает.

Сейчас пытаюсь сделать обратный процесс. Зная проекции вектора OP на оси-вектора U и V как получить координаты вектора OP в исходной системе?

Решение-то есть. Я знаю уравнение плоскости (в которой лежат U и V). Знаю значения двух скалярных произведений (две системы уравнений от трех неизвестных). Последовательно выражаю искомые координаты.

Но, как-то неочевидно всё и получаются большие формулы. Может есть способ это сделать векторно и аккуратно?

JANB
() автор топика
Ответ на: комментарий от amaora

Во! До этого дошел, спасибо Манханту. А обратный процесс? У меня есть вариант, но он длинный...

JANB
() автор топика
Ответ на: комментарий от JANB

Всё, я понял.

Я знаю проекции OP на оси-вектора U и V. Умножаю эти проекции на единичные вектора этих осей, получаю два вектора. ИХ произведение будет искомым вектором. Ну, плюс, сдвинуть относительно начала координат. Сделаю - выложу решение.

JANB
() автор топика
Ответ на: комментарий от JANB

Японский городовой! У тебя ж простая задача, которая решается матрично безо всяких проблем. Обратное преобразование == обратная матрица.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от JANB

ИХ произведение будет искомым вектором

В целом всё верно, но только не произведение, а сумма.

Manhunt ★★★★★
()
Ответ на: комментарий от Manhunt

Ты правда надеешься, что нубики смогут это прочитать?

Nubiki ne v sostojanii zajti v profil Eddy_Em i postavit User Script dlja greasemonkey?

dikiy ★★☆☆☆
()
Ответ на: комментарий от dikiy

Не в состоянии: просто не догадаются вчитаться в эдичкин профиль. Тогда уж надо в каждом сообщении с кракозябрами делать пост-скриптум с ссылкой на инструкцию по установке...

Manhunt ★★★★★
()
Последнее исправление: Manhunt (всего исправлений: 1)
Ответ на: комментарий от Manhunt

Не могут: просто не догадаются вчитаться в эдичкин профиль. Тогда уж надо в каждом сообщении с кракозябрами делать пост-скриптум с ссылкой на инструкцию по установке...

Ja v etom trede sledujuwim zhe posle matana postom ob etom i skazal, 4to skript nado stavit'.

dikiy ★★☆☆☆
()
Ответ на: комментарий от dikiy

Я сразу и без труда прочитал латех, большое спасибо!

Но я не силен в матричном исчислении, поэтому больше подошел вариант Манханта.

JANB
() автор топика
Ответ на: комментарий от JANB

Забыл вовремя выложить мой результат, но лучше поздно чем никогда

class Conv {
	XYZPlane *plane;
	XYZVector *f1, *f2;
	XYZVector *U, *V, *O;
public:
	Conv(XYZPlane *, XYZVector *, XYZVector *);
	Point *from3Dto2D(XYZPoint *) const;
	XYZPoint *from2Dto3D(Point *) const;
};


Conv::Conv(XYZPlane *pl, XYZVector *ff1, XYZVector *ff2) :
	plane(pl), f1(ff1), f2(ff2)
{
	U = XYZVector::sub(ff1,ff2);
	V = XYZVector::v_mul(U,pl->normal());
	O = XYZVector::middle(ff1,ff2);
}

Point *Conv::from3Dto2D(XYZPoint *p) const {
	XYZVector *OP = XYZVector::sub(new XYZVector(p), O);
	double tmpx = XYZVector::s_mul(OP,U) / sqrt(XYZVector::s_mul(U,U));
	double tmpy = XYZVector::s_mul(OP,V) / sqrt(XYZVector::s_mul(V,V));
	return new Point(tmpx,tmpy);
}

XYZPoint *Conv::from2Dto3D(Point *p) const {
	XYZVector *UP = U->one()->mul_c(p->x);
	XYZVector *VP = V->one()->mul_c(p->y);
	XYZVector *res = XYZVector::add(UP,VP);
	return res;	
}

http://pastebin.com/b6CgZf8b

JANB
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.