Здравствуйте
Сегодня утром проснулся и за полчаса все сделал. Наверное вчера был неудачный день
Все просто.
1) Общая часть
Нужно определить 2 системы координат: одну для пикселей, другую для 3D точек. Вычислить
относительные координаты в пиксельной системе и использовать их в 3D. Например, был имедж (0, 0)(100, 100) а после обрезки стал (20, 20)(75, 80) - значит относительные координаты новых точек (0.2, 0.2)(0.75, 0.8 )
2) Данные
Нужно определить операторы и писать в векторах иначе (если каждый раз повторять вычисления для 2 или 3 координат) никакой головы не хватит
struct Vec3D {
Vec3D & xyz( float _x, float _y, float _z ) { x = _x; y = _y; z = _z; return *this; }
float length( void ) const { return sqrt(x * x + y * y + z * z); } // длина вектора
// умножение и деление
friend Vec3D operator * ( const Vec3D & v, float t ) { Vec3D a; return a.xyz(v.x * t, v.y * t; v.z * t); }
friend Vec3D operator / ( const Vec3D & v, float t ) { Vec3D a; return a.xyz(v.x / t, v.y / t; v.z / t); }
// cложение и вычитание
friend Vec3D operator + ( const Vec3D & a, const Vec3D & b ) { Vec3D t; return t.xyz(a.x + b.x, a.y + b.y, a.z + b.z; }
friend Vec3D operator - ( const Vec3D & a, const Vec3D & b ) { Vec3D t; return t.xyz(a.x - b.x, a.y - b.y, a.z - b.z; }
// скалярное произведение - возвращает косинус угла между векторами помноженный на их длины
friend float operator * ( const Vec3D & a, const Vec3D & b ) { return a.x * b.x + a.y * b.y + a.z * b.z; }
// data
float x, y, z;
};
Все то же самое для Vec2D, только без z
3) Пусть точка задана так
struct CPoint {
Vec3D mPosOld; // исходная позиция в 3D
Vec3D mPosNew; // позиция в 3D после обрезки
Vec2D mPixOld; // пиксель имеджа до обрезки
Vec2D mPixNew; // пиксель имеджа после обрезки
};
Тогда
// mPixNew посчитано из имеджа для всех 4 точек теперь надо найти их mPosNew
void CalcQuad( CPoint quad[4] )
{
// строим пиксельную систему координат
Vec2D pixCenter = quad[0].mPixOld; // центр в точке 0
Vec2D pixX = quad[1].mPixOld - pixCenter; // первая ось 0->1 ("X")
Vec2D pixY = quad[3].mPixOld - pixCenter; // вторая ось 0->3 ("Y")
float lenX = pixX.length(); // длина первой оси
float lenY = pixY.length(); // длина второй оси
// строим 3D систему координат
Vec3D vecCenter = quad[0].mVecOld; // центр в точке 0
Vec3D vecX = quad[1].mVecOld - vecCenter; // первая ось 0->1 ("X")
Vec3D vecY = quad[3].mVecOld - vecCenter; // вторая ось 0->3 ("Y")
for (int i = 0; i < 4; ++i) {
// находим относительные пиксельные координаты
float relX = quad[i].mPixNew * pixX / (lenX * lenX);
float relY = quad[i].mPixNew * pixY / (lenY * lenY);
// переводим в 3D координаты
quad[i].mPosNew = vecCenter + vecX * relX + vecY * relY;
}
}