多边形点从三维到二维的正交投影,用于UV贴图
Orthographic projection of polygon points from 3D to 2D for UV mapping
我想使用简单的正交投影来变换或投影平面上多边形点的位置-用于UV映射,并进行绘制。代码:
CPolygonFaceRefArray lPolygons = lPolygonMesh.GetPolygons();
for( long f=0; f < lPolygons.GetCount(); f++ )
{
PolygonFace lFace = lPolygons[ f ];
CPointRefArray lPoints = lFace.GetPoints();
Point lPoint1 = lPoints[ 0 ];
Point lPoint2 = lPoints[ 1 ];
Point lPoint3 = lPoints[ 2 ];
CVector3 lPoint1Position = lPoint1.GetPosition();
CVector3 lPoint2Position = lPoint2.GetPosition();
CVector3 lPoint3Position = lPoint3.GetPosition();
_LogValue2( f, L"--------------------------------------" );
// Vector A->B, that becomes the X axis of the local plane.
CVector3 lLocalX = lLocalX.Sub( lPoint1Position, lPoint2Position );
lLocalX.NormalizeInPlace();
// Vector A->C
CVector3 lVector13 = lVector13.Sub( lPoint1Position, lPoint3Position );
lVector13.NormalizeInPlace();
// Determine the Z vector of the local plane:.
CVector3 lLocalZ = lLocalZ.Cross( lLocalX, lVector13 );
lLocalZ.NormalizeInPlace();
// Determine Y vector of the local plane, assuming that it’s perpendicular to already known X and Z.
CVector3 lLocalY = lLocalY.Cross( lLocalZ, lLocalX );
lLocalY.NormalizeInPlace();
// In result we got three axis of the local plane:
// lLocalX.Dot( lLocalY ) == lLocalX.Dot( lLocalZ ) == lLocalY.Dot( lLocalZ ) == 0;
/*
Now use system of equations to determine the positions of all points in reference to the local plane.
double GetBase(const double& a1, const double& b1, const double& c1, const double& a2, const double& b2, const double& c2, const double& a3, const double& b3, const double& c3 )
{return (a1*b2*c3)+(a3*b1*c2)+(a2*b3*c1)-((a3*b2*c1)+(a1*b3*c2)+(a2*b1*c3));}
double GetX(const double& a1, const double& b1, const double& c1, const double& d1, const double& a2, const double& b2, const double& c2, const double& d2, const double& a3, const double& b3, const double& c3, const double& d3, const double& in_Base)
{return ( (d1*b2*c3)+(d2*b1*c2)+(d2*b3*c1)-((d3*b2*c1)+(d1*b3*c2)+(d2*b1*c3)) ) / in_Base;}
double GetY(const double& a1, const double& b1, const double& c1, const double& d1, const double& a2, const double& b2, const double& c2, const double& d2, const double& a3, const double& b3, const double& c3, const double& d3, const double& in_Base)
{return ( (a1*d2*c3)+(a3*d1*c2)+(a2*d3*c1)-((a3*d2*c1)+(a1*d3*c2)+(a2*b1*c3)) ) / in_Base;}
double GetZ(const double& a1, const double& b1, const double& c1, const double& d1, const double& a2, const double& b2, const double& c2, const double& d2, const double& a3, const double& b3, const double& c3, const double& d3, const double& in_Base)
{return ( (a1*b2*d3)+(a3*b1*d2)+(a2*b3*d1)-((a3*b2*d1)+(a1*b3*d2)+(a2*b1*d3)) ) / in_Base;}
*/
double fU;
double fV;
double fW;
double fBase;
// For each point, except the first one (lPoint1Position), which we aleady know.
for( long p=1; p < lPoints.GetCount(); p++ )
{
Point lPoint = lPoints[ p ];
CVector3 lPointPosition = lPoint.GetPosition();
CVector3 lPointVector = lPointVector.Sub( lPoint1Position, lPointPosition );
fBase = GetBase(
lLocalX.GetX(), lLocalY.GetX(), lLocalZ.GetX(),
lLocalX.GetY(), lLocalY.GetY(), lLocalZ.GetY(),
lLocalX.GetZ(), lLocalY.GetZ(), lLocalZ.GetZ() );
fU = GetX( lLocalX.GetX(), lLocalY.GetX(), lLocalZ.GetX(), lPointVector.GetX(),
lLocalX.GetY(), lLocalY.GetY(), lLocalZ.GetY(), lPointVector.GetY(),
lLocalX.GetZ(), lLocalY.GetZ(), lLocalZ.GetZ(), lPointVector.GetZ()
,fBase );
fV = GetY( lLocalX.GetX(), lLocalY.GetX(), lLocalZ.GetX(), lPointVector.GetX(),
lLocalX.GetY(), lLocalY.GetY(), lLocalZ.GetY(), lPointVector.GetY(),
lLocalX.GetZ(), lLocalY.GetZ(), lLocalZ.GetZ(), lPointVector.GetZ()
,fBase );
fW = GetZ( lLocalX.GetX(), lLocalY.GetX(), lLocalZ.GetX(), lPointVector.GetX(),
lLocalX.GetY(), lLocalY.GetY(), lLocalZ.GetY(), lPointVector.GetY(),
lLocalX.GetZ(), lLocalY.GetZ(), lLocalZ.GetZ(), lPointVector.GetZ()
,fBase );
_LogRoundValue3( p, fU, fV, fW );
}
// Result for a cube with the center in 0,0,0 (global coords) is:
// INFO : Values: 0, --------------------------------------
// INFO : 1 = 0, 0, 0
// INFO : 2 = 0, 1, 0
// INFO : 3 = 0, 1, 0
// INFO : Values: 1, --------------------------------------
// INFO : 1 = 1, 1, 0
// INFO : 2 = 1, 1, 0
// INFO : 3 = 0, 1, 0
// INFO : Values: 2, --------------------------------------
// INFO : 1 = 1, 0, 0
// INFO : 2 = 1, 1, 0
// INFO : 3 = 0, 1, 0
// INFO : Values: 3, --------------------------------------
// INFO : 1 = 1, 0, 0
// INFO : 2 = 1, 1, 0
// INFO : 3 = 0, 1, 0
// INFO : Values: 4, --------------------------------------
// INFO : 1 = 1, 0, 0
// INFO : 2 = 1, 1, 0
// INFO : 3 = 0, 1, 0
// INFO : Values: 5, --------------------------------------
// INFO : 1 = 0, 0, 0
// INFO : 2 = 0, 1, 0
// INFO : 3 = 0, 1, 0
// and for a rotated cube at the same place:
// INFO : Values: 0, --------------------------------------
// INFO : 1 = 0.027506, 0.033672, 0
// INFO : 2 = 0.487751, 0.969746, 0
// INFO : 3 = 0.460245, 1, 0
// INFO : Values: 1, --------------------------------------
// INFO : 1 = 1.15549, 0.753083, 0
// INFO : 2 = 1.03428, 1, 0
// INFO : 3 = -0.121205, 1, 0
// INFO : Values: 2, --------------------------------------
// INFO : 1 = 1, 0.04442, 0
// INFO : 2 = 1, 1.04442, 0
// INFO : 3 = 0, 1, 0
// INFO : Values: 3, --------------------------------------
// INFO : 1 = 1, -0.093859, 0
// INFO : 2 = 1, 0.906141, 0
// INFO : 3 = 0, 1, 0
// INFO : Values: 4, --------------------------------------
// INFO : 1 = 1, -0.04442, 0
// INFO : 2 = 1, 0.95558, 0
// INFO : 3 = 0, 1, 0
// INFO : Values: 5, --------------------------------------
// INFO : 1 = 0.027506, 0.09418, 0
// INFO : 2 = -0.43274, 1.03025, 0
// INFO : 3 = -0.460245, 1, 0
}
这只是每个多边形的投影,我假设所有多边形点都在同一个局部平面上,这并不总是这样,但并不重要。
我从确定局部平面开始,然后使用方程组试图找到局部平面上点的坐标。然而,结果是错误的。
代码使用XSI的API,矢量类文档在这里:
http://download.autodesk.com/global/docs/softimage2013/en_us/sdkguide/index.html?url=si_cpp/classXSI_1_1MATH_1_1CVector3.html,topicNumber=si-cpp_classXSI_1_1MATH_1_1CVector_3_html
- 第一个问题是:这是一种正确的方法吗
- 如果是,那它怎么了
…是的,我读过http://en.wikipedia.org/wiki/3D_projection:(
如果有任何建议,我将不胜感激。
我建议您使用点积计算映射坐标:
fU = lPointVector.Dot(lLocalX);
fV = lPointVector.Dot(lLocalY);
fW = lPointVector.Dot(lLocalZ); // should be zero if points lie in plane
这将把你从三维坐标带到二维坐标,这似乎就是你所要求的。如果没有,你应该澄清你的问题。
相关文章:
- 更改高度贴图,使其在 4x4 网格上显示 16 个 hieghtmap
- 深度缓冲区未填充阴影贴图渲染通道中的数据
- OpenGL - 阴影贴图/深度贴图给出奇怪的结果
- C++如何创建自动投射贴图?
- OpenGL 高度贴图渲染器无法生成平滑地形
- 从Qt3D PickEvent获取漫反射贴图RGB数据
- Opengl es 2.0中带有立方体贴图的阴影贴图
- Push_front()用于矢量,运算符++用于贴图
- 带法线贴图的Binormal和Tangent
- 从包含贴图的deque中删除元素
- 用于多个目标的2D平铺贴图的路径查找
- 以一个键和一对作为值对贴图进行排序
- 具有2个值的STL贴图
- 增加贴图的值
- 阴影贴图.帧缓冲区错误36060
- STL中关联数组(贴图)的速度
- 试图找到贴图的幅值图像
- 当使用带有透明度的阴影贴图技术时,为什么这条黑线会出现在投影阴影的边界上?
- 多边形点从三维到二维的正交投影,用于UV贴图
- 阴影贴图投影不正确