目录
- 不旋转的长方体
- 计算旋转矩阵及旋转后的长方体
- 计算旋转矩阵
- 计算旋转后的长方体
- 判断点是否在旋转后的长方体内
不旋转的长方体
如果这个长方体是规则的,不进行任何旋转,可以先计算长方体的BoundingBox,判断点是否在3D的BoundingBox中即可。
计算旋转矩阵及旋转后的长方体
计算旋转矩阵
这里使用的是glm库,下面是根据旋转角度,旋转中心和旋转轴计算的旋转矩阵:
glm::mat4 getMatrix(float angleInDegrees, glm::vec3 rotationCenter, glm::vec3 rotationAxis)
{
// 将角度转换为弧度
float angleInRadians = glm::radians(angleInDegrees);
// 创建反向平移矩阵,将旋转中心移动到原点
glm::mat4 translateToOrigin = glm::translate(glm::mat4(1.0f), -rotationCenter);
// 创建旋转矩阵,围绕原点进行旋转
glm::mat4 rotationMatrix = glm::rotate(glm::mat4(1.0f), angleInRadians, rotationAxis);
// 创建平移矩阵,将旋转中心移动回原来的位置
glm::mat4 translateBack = glm::translate(glm::mat4(1.0f), rotationCenter);
// 将以上矩阵相乘,得到最终的变换矩阵
return translateBack * rotationMatrix * translateToOrigin;
}
计算旋转后的长方体
下面是根据一个不旋转的长方体的角点和旋转矩阵计算当前长方体的位置,8个顶点位置是固定的,位置如图所示:
实现代码如下所示:
std::vector<glm::vec3>computeCube(const glm::vec3 minBounds, const glm::vec3 maxBounds,glm::mat4 matrix)
{
std::vector<glm::vec3> cubeVerticex;
cubeVerticex.resize(8);
cubeVerticex[0] = matrix* glm::vec4(maxBounds.x, minBounds.y, minBounds.z, 1.0);
cubeVerticex[1] = matrix* glm::vec4(minBounds, 1.0);
cubeVerticex[2] = matrix* glm::vec4(minBounds.x, maxBounds.y, minBounds.z, 1.0);
cubeVerticex[3] = matrix* glm::vec4(maxBounds.x, maxBounds.y, minBounds.z, 1.0);
cubeVerticex[4] = matrix* glm::vec4(maxBounds.x, minBounds.y, maxBounds.z, 1.0);
cubeVerticex[5] = matrix* glm::vec4(minBounds.x, minBounds.y, maxBounds.z, 1.0);
cubeVerticex[6] = matrix* glm::vec4(minBounds.x, maxBounds.y, maxBounds.z, 1.0);
cubeVerticex[7] = matrix* glm::vec4(maxBounds, 1.0);
return cubeVerticex;
}
判断点是否在旋转后的长方体内
这里参考了已有代码,但是作者使用的是在原点的长方体,我们的长方体在大部分情况下是不在原点的,下面是根据原作者的代码进行的修改,可以是不在原点的长方体,但是长方体的8个顶点必须是上面的顺序,不可更改。代码如下:
bool isPointInsideCube(glm::vec3 p,std::vector<glm::vec3> vertices) {
//长方体必须是8个顶点
if(vertices.size()!=8)
{
return false;
}
//首先判断点是否在左右两面的中间 此时法线为y轴
vec3 vector_DP;
vec3 vector_EP;
vec3 vector_DE;//法线y
//计算向量DE
vector_DE.x=vertices[7].x-vertices[4].x;vector_DE.y=vertices[7].y-vertices[4].y;vector_DE.z=vertices[7].z-vertices[4].z;
//计算向量DP
vector_DP.x=p.x-vertices[4].x;vector_DP.y=p.y-vertices[4].y;vector_DP.z=p.z-vertices[4].z;
//计算向量EP
vector_EP.x=p.x-vertices[7].x;vector_EP.y=p.y-vertices[7].y;vector_EP.z=p.z-vertices[7].z;
//计算向量点乘的结果
//DP点乘DE
double DP_DE;
DP_DE=vector_DP.x*vector_DE.x+vector_DP.y*vector_DE.y+vector_DP.z*vector_DE.z;
//EP点乘DE
double EP_DE;
EP_DE=vector_EP.x*vector_DE.x+vector_EP.y*vector_DE.y+vector_EP.z*vector_DE.z;
//然后判断点是否在上下两面的中间 此时法线为z轴
vec3 vector_AP;
vec3 vector_AD;//法线y
//计算向量AP
vector_AP.x=p.x-vertices[0].x;vector_AP.y=p.y-vertices[0].y;vector_AP.z=p.z-vertices[0].z;
//计算向量AD
vector_AD.x=vertices[4].x-vertices[0].x;vector_AD.y=vertices[4].y-vertices[0].y;vector_AD.z=vertices[4].z-vertices[0].z;
//计算向量点乘的结果
//AD AP
double AD_AP;
AD_AP=vector_AD.x*vector_AP.x+vector_AD.y*vector_AP.y+ vector_AD.z*vector_AP.z;
//AD DP
double AD_DP;
AD_DP=vector_AD.x*vector_DP.x+vector_AD.y*vector_DP.y+ vector_AD.z*vector_DP.z;
//最后判断点是否在前后两面的中间 此时法线为x轴
vec3 vector_OA;//法线
vec3 vector_OP;
vector_OA.x=vertices[0].x-vertices[1].x;vector_OA.y=vertices[0].y-vertices[1].y;vector_OA.z=vertices[0].z-vertices[1].z;
vector_OP.x=p.x-vertices[1].x;vector_OP.y=p.y-vertices[1].y;vector_OP.z=p.z-vertices[1].z;
//计算向量点乘的结果
//OP OA
double OP_OA;
OP_OA=vector_OP.x*vector_OA.x+vector_OP.y*vector_OA.y+vector_OP.z*vector_OA.z;
//AP OA
double AP_OA;
AP_OA=vector_AP.x*vector_OA.x+vector_AP.y*vector_OA.y+vector_AP.z*vector_OA.z;
if (DP_DE*EP_DE<0&&AD_AP*AD_DP<0&&OP_OA*AP_OA<0)
{
return true;
}else
{
return false;
}
}