Arrays MATLAB-获取点阵列之间的角度
为了进行照明分析,基于,我尝试确定一组灯光和固体表面上的一系列点的三个方面: (图像键:蓝色大点是指示照明方向的灯光,小点是我的曲面上的点)Arrays MATLAB-获取点阵列之间的角度,arrays,matlab,matrix,angle,Arrays,Matlab,Matrix,Angle,为了进行照明分析,基于,我尝试确定一组灯光和固体表面上的一系列点的三个方面: (图像键:蓝色大点是指示照明方向的灯光,小点是我的曲面上的点) 1) 每个灯光和每个点之间的距离 2) 每个灯光所面对的方向与所有点的法向量之间的角度: 请注意,在这张图片中,我复制了法向量,并将其移动以更清晰地显示角度 3) 每个灯光所面对的方向之间的角度,以及从该灯光到实体上所有点的矢量: 最初,我在实体上的所有灯光和点上嵌套了for循环,但现在我正在尽我最大的努力以真正的MATLAB风格使用矩阵: 我
- 1) 每个灯光和每个点之间的距离
- 2) 每个灯光所面对的方向与所有点的法向量之间的角度:
- 3) 每个灯光所面对的方向之间的角度,以及从该灯光到实体上所有点的矢量:
for
循环,但现在我正在尽我最大的努力以真正的MATLAB风格使用矩阵:
我已经使用
pdist2
功能找到了所有点之间的距离,但没有找到类似的方法来找到灯光和所有点之间的角度,也没有找到灯光和点的法向量。我更喜欢用矩阵方法,而不是我一直使用的迭代方法
考虑到我设置了数据,其中Lmat
的每一列都有我的x,y,z
灯光的位置向量Dmat
给出每个灯光的x、y、z
方向,因此这两个矩阵中的每一行的组合完全定义灯光及其所面对的方向。类似地,Omega
和nmat
对曲面上的点执行相同的操作
我相当确信,为了获得角度,我想做一些事情,大致如下:
distMatrix = pdist2(Omega, Lmat);
LmatNew = zeros(numPoints, numLights, 3);
DmatNew = zeros(numPoints, numLights, 3);
OmegaNew = zeros(numPoints, numLights, 3);
nmatNew = zeros(numPoints, numLights, 3);
for i = 1:numLights
LmatNew(:,i,1) = Lmat(i,1);
LmatNew(:,i,2) = Lmat(i,2);
LmatNew(:,i,3) = Lmat(i,3);
DmatNew(:,i,1) = Dmat(i,1);
DmatNew(:,i,2) = Dmat(i,2);
DmatNew(:,i,3) = Dmat(i,3);
end
for j = 1:numPoints
OmegaNew(j,:,1) = Omega(j,1);
OmegaNew(j,:,2) = Omega(j,2);
OmegaNew(j,:,3) = Omega(j,3);
DmatNew(:,i,1) = Dmat(i,1);
DmatNew(:,i,2) = Dmat(i,2);
DmatNew(:,i,3) = Dmat(i,3);
end
angleMatrix = -dot(LmatNew-OmegaNew, DmatNew, 3);
angleMatrix = atand(angleMatrix);
angleMatrix = angleMatrix.*(angleMatrix > 0);
但我在概念上陷入了困境,试图弄清楚在我的点产品发布后该做什么
我走对了吗?是否有一个内置的角度相当于我忽略的pdist2
谢谢大家的帮助,很抱歉画了这些图片
上下文:此图显示我的灯光(蓝色大点)、灯光朝向的方向(黑色小痕迹)以及我的模型。根据,没有内置函数来计算向量之间的角度。但是,可以使用三角学计算角度
投入
不幸的是,由于您没有详细解释输入数据,我将假设您有一个矩阵Lmat
,其中每行包含光源的位置向量,以及一个矩阵Dmat
,其中包含光源的方向向量,大小均为n×3,其中n是场景中光源的数量
矩阵Omega
和Nmat
的大小假定为m×3,包含所有m个曲面点的位置向量和法向量。期望的结果是所有光方向向量和表面法向量之间的角度,其中有n个⋅m、 以及光方向向量和将光连接到表面上每个点的向量之间的角度,其中有n个⋅我也是
要获得所有光源和曲面点组合的结果,必须垂直重复输入矩阵:
Lmat = repmat(Lmat, size(Omega,1), 1);
Dmat = repmat(Dmat, size(Omega,1), 1);
Omega = repmat(Omega, size(Lmat,1), 1);
Nmat = repmat(Nmat, size(Lmat,1), 1);
使用内积/点积
定义了两个向量的内积
其中θ是两个向量之间的角度。对方程重新排序会产生
因此,您可以计算方向向量Dmat
和法向量Nmat
之间的角度,如下所示:
normProd = sqrt(sum(Dmat.^2,2)).*sqrt(sum(Nmat.^2,2));
anglesInDegrees = acos(dot(Dmat.',Nmat.')' ./ normProd) * 180 / pi;
normCross = sqrt(sum(cross(Dmat,Nmat,2).^2,2));
anglesInDegrees = atan2(normCross,dot(Dmat.',Nmat.')') * 180/pi;
要计算光到点矢量和方向矢量之间的角度,只需将Nmat
替换为Omega-Lmat
使用向量积/叉积
一直以来,上述方法在很小的(θ)范围内存在精度问题≈ 0°)或非常大(θ≈ 180°)角度。建议的解决方案是使用叉积和内积计算角度
两个向量的向量积的范数为
您可以将其与上面的内积定义相结合,以获得
显然,可以将其重新排序为:
相应的MATLAB代码如下所示:
normProd = sqrt(sum(Dmat.^2,2)).*sqrt(sum(Nmat.^2,2));
anglesInDegrees = acos(dot(Dmat.',Nmat.')' ./ normProd) * 180 / pi;
normCross = sqrt(sum(cross(Dmat,Nmat,2).^2,2));
anglesInDegrees = atan2(normCross,dot(Dmat.',Nmat.')') * 180/pi;
那么我是否正确理解了你的问题:你在寻找点与点之间的角度?“这有意义吗?”罗伯特特勒说“考虑到我设置了数据,其中
Lmat
的每一列都有我的x,y,z
灯光位置向量Dmat
给出每个灯光的x、y、z
方向,因此这两个矩阵中的每一行的组合完全定义灯光及其所面对的方向。类似地,Omega
和nmat
也对曲面上的点执行相同的操作。”“我使用pdist2功能找到了所有点之间的距离,我还找到了灯光所面对的方向和方向之间的每个角度,但没有找到类似的方法来找到点之间的角度。“–这句话少了一些东西。另外,你能重新表述你的问题,让它更清楚地表明你在寻找什么吗?“就我个人而言,我说不出你们已经拥有了什么,你们正在努力实现什么。”达斯丁戈内森对不起,我的校对真的很差。现在好点了吗?现在清楚多了。“考虑到我已经列出了数据,Lmat的每一列都有我灯光的x,y,z位置向量”——我想你的意思是说矩阵的每一行都是一个位置向量,至少我在回答中假设了这一点。