目录
- 不旋转的长方体
- 计算旋转矩阵及旋转后的长方体
- 计算旋转矩阵
- 计算旋转后的长方体
- 判断点是否在旋转后的长方体内
不旋转的长方体
如果这个长方体是规则的,不进行任何旋转,可以先计算长方体的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//计算向量DEvector_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;//计算向量DPvector_DP.x=p.x-vertices[4].x;vector_DP.y=p.y-vertices[4].y;vector_DP.z=p.z-vertices[4].z;//计算向量EPvector_EP.x=p.x-vertices[7].x;vector_EP.y=p.y-vertices[7].y;vector_EP.z=p.z-vertices[7].z;//计算向量点乘的结果//DP点乘DEdouble DP_DE;DP_DE=vector_DP.x*vector_DE.x+vector_DP.y*vector_DE.y+vector_DP.z*vector_DE.z;//EP点乘DEdouble 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//计算向量APvector_AP.x=p.x-vertices[0].x;vector_AP.y=p.y-vertices[0].y;vector_AP.z=p.z-vertices[0].z;//计算向量ADvector_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 APdouble AD_AP;AD_AP=vector_AD.x*vector_AP.x+vector_AD.y*vector_AP.y+ vector_AD.z*vector_AP.z;//AD DPdouble 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 OAdouble 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;}
}