英文:
How to calculate other perspectives on amount of points
问题
以下是翻译好的部分:
我有一个实际上很琐碎的问题,但我就是找不到解决方案。
以下是问题的描述:
我在xy平面上有一组特定的点。如果你将它们绘制出来(从z轴方向看),它们形成一个圆。
现在我想改变视角,即不再垂直于xy平面,而是以一个角度观察。结果应该是一个椭圆,而不是一个圆。
实际上,这与Matlab为3D散点图的旋转所做的事情几乎相同。也许我只是不知道正确的搜索词。
我已经尝试过使用旋转矩阵来转换这些点,但每次都得到了十字形的形状。
请参见我的Matlab代码如下:
r=1;
a=10;
Rx=[1,0,0; 0,cosd(a),-sind(a); 0,sind(a),cosd(a)];
x=[];
y=[];
z=[];
for phi=0:10:360
x=[x; r*cosd(phi)];
y=[y; r*sind(phi)];
z=[z; 0];
end
Points = [x,y,z];
Points_new=[];
for p=1:numel(Points)/3
Points_new = [Points_new; Rx*Points(p,:)'];
end
figure
scatter(Points(:,1), Points(:,2), '+')
hold on
scatter(Points_new(:,1), Points_new(:,2), '+')
axis equal
注意:我已经将代码中的引号(')由HTML实体编码(')更改为正常的单引号('),以使代码在翻译中更容易阅读。
英文:
I have a actually trivial question, but I just can't find a solution yet.
The following problem:
I have a certain set of points in the xy plane. If you plot them (viewed from the direction of the z-axis) they form a circle.
Now I want to change the perspective, i.e. no longer look perpendicular to the xy plane, but at an angle. The result should then be an ellipse and not a circle.
So it's practically the same as what Matlab does for a spin of a 3D scatter. Maybe I just don't know the wright word for searching.
I've already tried something with the rotation matrix by transforming the points with it, but every time something came out in the form of a cross.
See my Matlab Code below:
r=1;
a=10;
Rx=[1,0,0; 0,cosd(a),-sind(a); 0,sind(a),cosd(a)];
x=[];
y=[];
z=[];
for phi=0:10:360
x=[x; r*cosd(phi)];
y=[y; r*sind(phi)];
z=[z; 0];
end
Points = [x,y,z];
Points_new=[];
for p=1:numel(Points)/3
Points_new = [Points_new; Rx*Points(p)];
end
figure
scatter(Points(:,1), Points(:,2), '+')
hold on
scatter(Points_new(:,1), Points_new(:,2), '+')
axis equal
答案1
得分: 0
你的问题是你错误地应用了旋转矩阵。让我们看看这段代码:
在循环中,p
是一个标量值,它从 1 开始。现在 Points(p)
将是 Points(1)
,即 1。Rx*1
就是 Rx
,这是一个 3x3 矩阵。因此,循环将把 3x3 矩阵添加到数组 Points_new
中,而不是一个向量!。
确实,当我们查看数组的大小时,Points
有 37 行,而 Points_new
有 111 行,对应于 Points
的每行有三行。
你可以通过使用适当的索引来修复这个问题,Points(p,:)
是包含你想要转换的 x、y、z 坐标的行。现在我们需要通过转置将其放入正确的形状,然后再次转置结果:
但请注意,这是非常低效的,有两个原因。首先,我们在每次迭代时都增加了数组 Points_new
的大小。相反,首先为其分配最终大小,然后通过对其进行索引赋值:
(我还将 numel(...)/3
更改为 size(...,1)
,这样更清楚明了。)
第二个原因是你正在进行不必要的循环。MATLAB 循环现在非常快,但通常不使用显式循环会稍快一些,并且更清晰(更容易编写、更容易阅读、更容易维护):
或者,通过右乘运算应用旋转矩阵:
(显然,对于你的第一个循环,我们可以讨论相同的情况,它可以很简单地实现为数组函数)。
英文:
Your issue is that you apply the rotation matrix wrong. Let's look at this code:
Points_new=[];
for p=1:numel(Points)/3
Points_new = [Points_new; Rx*Points(p)];
end
In the loop, p
is a scalar value, it starts with 1. Now Points(p)
will be Points(1)
, which is 1. Rx*1
is just Rx
, the 3x3 matrix. So the loop is adding 3x3 matrices to the array Points_new
, not a vector!.
And, indeed, when we look at the sizes of the arrays, Points
has 37 rows, whereas Points_new
has 111, three rows for each one row in Points
.
You can fix this by using proper indexing, Points(p,:)
is the row containing the x,y,z coordinates that you want to transform. Now we need to put that in the right shape by transposing, and then transpose the result again:
Points_new=[];
for p=1:numel(Points)/3
Points_new = [Points_new; (Rx*Points(p,:).').'];
end
But note that this is very inefficient, for two reasons. One, we're increasing the size of the array Points_new
every iteration. Instead, allocate the array to its final size first, then assign by indexing into it:
Points_new = zeros(size(Points));
for p = 1:size(Points,1)
Points_new(p,:) = Rx*Points(p,:).';
end
(Note I also changed numel(...)/3
into size(...,1)
, which is clearer in intention.)
The second reason it's inefficient is that you're looping where no loop is necessary. MATLAB loops are very fast nowadays, but not using explicit loops is often a bit faster, and a lot cleaner (easier to write, easier to read, easier to maintain):
Points_new = (Rx * Points.').';
Alternatively, apply the rotation matrix by right multiplication:
Points_new = Points * Rx.';
(obviously the same discussion can be had about your first loop, which can be implemented quite simply as an array function).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论