Math 制作三维聚光灯圆锥体矩阵

Math 制作三维聚光灯圆锥体矩阵,math,3d,matrix,Math,3d,Matrix,如何创建转换矩阵4x4,将高度为1、直径为1的圆柱体转换为表示聚光灯位置、方向和截止角的圆锥体 -编辑- 换句话说:如何通过适当的变换矩阵绘制圆柱体来绘制表示聚光灯的圆锥体 -编辑2- 以下伪代码给出了预期的结果: PushMatrix(); LoadIdentity(); Perspective(lightCutoffAngle * 2, 1, 0.001, 10000); // fov, aspect, near, far LookAt(lightPos.x,lightPos.y,light

如何创建转换矩阵4x4,将高度为1、直径为1的圆柱体转换为表示聚光灯位置、方向和截止角的圆锥体

-编辑- 换句话说:如何通过适当的变换矩阵绘制圆柱体来绘制表示聚光灯的圆锥体

-编辑2- 以下伪代码给出了预期的结果:

PushMatrix();
LoadIdentity();
Perspective(lightCutoffAngle * 2, 1, 0.001, 10000); // fov, aspect, near, far
LookAt(lightPos.x,lightPos.y,lightPos.z, lightDir.x,lightDir.y,lightDir.z, 0,0,1);
Matrix44 mat = GetModelViewMatrix();
mat.Invert();
PopMatrix();
MultMatrix(mat);
DrawCone(1,1); // diameter, height

我知道你想要一个矩阵,比如

x/y 0   0  0
 0  y   0  0
 0  0  z/y 0
 0  0   0  1
x = x/y  or x(1-y)
y =  y
z = z/y  or z(1-y)
x = tan^-1(L) * [ x/y  or x(1-y) ]
y =  y
z = tan^-1(L) * [ z/y  or z(1-y) ]
或者可能

x(1-y) 0   0    0
  0    1   0    0
  0    0 z(1-y) 0
  0    0   0    1
如果圆锥体是以原点为中心的圆,位于沿y轴拉伸1个单位的z-x轴上。其中一个矩阵应该可以工作,因为圆锥体的点沿y轴向上移动得越远,您越希望它们朝y轴移动

希望这能帮你解决问题,或者至少给你一个好的开始。。。现在让我休息一下

更新

正如评论中指出的那样,这需要工作。我想我有点过火了。如果用1代替x和z,那么用向量乘以矩阵。你会得到这样的结果

x/y 0   0  0
 0  y   0  0
 0  0  z/y 0
 0  0   0  1
x = x/y  or x(1-y)
y =  y
z = z/y  or z(1-y)
x = tan^-1(L) * [ x/y  or x(1-y) ]
y =  y
z = tan^-1(L) * [ z/y  or z(1-y) ]
更新

为了考虑光线的角度,我们将缩放圆锥体的半径,但保持单位长度。如果我们有光的角度,这是从中心点开始的,而不是从边到边,我们可以说我们的圆锥体需要的半径是tan^-1L

所以如果我们把这个因素考虑进去,我们的期末数学应该是

x/y 0   0  0
 0  y   0  0
 0  0  z/y 0
 0  0   0  1
x = x/y  or x(1-y)
y =  y
z = z/y  or z(1-y)
x = tan^-1(L) * [ x/y  or x(1-y) ]
y =  y
z = tan^-1(L) * [ z/y  or z(1-y) ]

通常不会使用矩阵将圆柱体变换为圆锥体。这是因为它涉及两个组件的缩放,其中缩放因子取决于第三个组件

我认为你可以通过构建look at matrix gluLookAt或D3DXMatrxiLookAtLH并将其与透视矩阵gluPerspective或D3DXMatrixPerspectiveFovLH相乘来构建这样的矩阵,但我严重怀疑你是否能够用OpenGL或D3D渲染圆柱体。这是因为为了使投影工作,3D渲染使用第四矢量分量-W,该分量是通过将矢量与投影矩阵相乘来计算的。W组件通常是隐藏的,并且仅通过着色器可用。搞乱这个组件通常会搞乱任何几何体,并且在不使用w组件的情况下无法将圆柱体转换为圆锥体。也就是说,如果你把圆柱体变换成圆锥体,你就必须使用W,这将破坏投影变换

我建议通常从顶点构建圆柱体。这在D3D和OpenGL中都不难

如果确实要将圆柱体变换为圆锥体,则编写用于变换圆柱体的顶点着色器会更容易,尽管确保所有法线都正确可能是一个问题

如果您想知道哪些对象击中了光锥,请使用数学和碰撞检测。这并不难

如果要渲染灯光圆锥体内可见的对象,请使其他渲染目标或帧缓冲区、视口或其他对象从灯光的角度可见

关于光截止角


给定点p、灯光位置L、灯光方向LDir和截止角,您可以轻松检查p是否在灯光圆锥体内。要做到这一点,您需要完全或一半截止角的余弦,这取决于截止角是相对于灯光方向计算的,还是确定圆锥体的宽度。使矢量PDir=P-L,对PDir进行规格化,并计算规格化PDir和规格化LDir之间的点积,这将给出点P处光方向之间的夹角余弦。如果PDir和LDir之间的余弦大于光锥的余弦,则该点位于光锥内。

您使用的是openGL还是DirectX?或者其他一些图形API?你真的想使用灯光吗?或者你只是想模拟一个圆锥体?我想创建一个4x4矩阵,它将在聚光灯圆锥体中绘制物体。这意味着尺寸为1x1x1的圆柱体将精确地表示聚光灯圆锥体。你不能用矩阵“绘制”物体。您可以使用矩阵来表示对象在绘制之前所经历的移动。你想成为聚光灯的模特吗?记住,你不能“看到”你的光点,只能看到它所照亮的东西。我想帮你,但我发现很难弄清楚你到底是什么。哦,我现在明白了,你不是一个能把圆柱体变成圆锥体的矩阵。我的头突然有点痛,但我在想你会怎么做。如果你的圆锥体是沿着y轴排列的,并且是你说的单位大小,那么你需要相对于y轴缩放x轴和z轴。试着去想。。。让我回到这一个。这不起作用,因为你不能用这种方式将x和y乘以z。谢谢你的回答,但是我想知道如何考虑聚光灯截止角。你需要先缩放圆锥体的直径,以便得到正确的角度,或者试着将角度考虑到矩阵中。这是可能的,只是很难在你的脑海中思考。哥们,这是一个正常的缩放矩阵。如果您在上使用此按钮,气缸将变为压扁气缸
e、 但不会成为圆锥体,无论您如何计算缩放组件。使用圆柱体构建OpenGL/D3D应用程序,并亲自查看。在不使用w组件的情况下,不能将x除以z或y,或将x乘以z或y与矩阵相乘。要清楚,这不是一个可以设置为模型/视图或投影的矩阵。这些矩阵是“静态的”。使用顶点着色器可以“调制”圆柱体的几何体。我的方法意味着您获取一个点的“数组”,并将此逻辑应用于所有点,一次一个。我所说的tan^-1L是指反tan,不是tanLYou的某个根可以做到这一点。您正在相对于y缩放x和z。你不需要触摸WI将使用顶点着色器将我的圆柱体转换为圆锥体,但我不知道如何设置转换矩阵,将圆柱体的顶点转换为适合聚光灯圆锥体的圆锥体。这部分是我的观点,只要将矩阵应用于构成圆锥体的一组点,就不需要开始使用顶点着色器。无论哪种方法,你都需要一个矩阵来将圆柱体变换成圆锥体,或者首先要有圆锥体的几何图形。@Coshman不,你不能这样做。可以按固定因子缩放所有向量分量,可以将所有3个分量相加,但不能使用矩阵和不使用第4个分量将向量x和y乘以同一向量的z分量。这不是仿射变换。如果你不同意的话,给我一个矩阵,可以这样做。不是这样的矩阵,但你仍然可以将圆柱体按一定的比例缩放成圆锥体。