【发布时间】:2014-02-09 01:17:36
【问题描述】:
我有一个任务是渲染一个圆环。这是我第一次使用 matlab,我已经设法用一些可怕的混乱代码完成了 2/3 的部分。
作业的第一步是将一个圆渲染为一组 20 个点。我为此制作了:
circle (IMG)
然后下一步是旋转和平移那个圆并绘制 20 次以表示圆环形状,所以我得到了这个:
torus points (IMG)
下一步是从顶点列表中渲染此圆环的 3d 表示。
我所拥有的是一个 400x3 矩阵中的大量顶点列表,如下所示:
7.66478245119846 -1.84059939326890 0.292371704722737
7.53434247103331 -1.79821687453702 0.573576436351046
7.32764268084884 -1.73105604149887 0.798635510047293
7.06491629627043 -1.64569106442929 0.945518575599317
6.77188080634298 -1.55047806205660 0.999847695156391
6.47722056651889 -1.45473714644104 0.956304755963036
... ... ...
其中每 20 行是另一个圆圈。
作业建议我使用 surf 函数来渲染它,但我不知道如何。我见过的所有示例都使用 surf 来表示被高度值扭曲的二维平面。这似乎根本不适合渲染这种 3 维形状。
我正在尝试的方法是构建一个人脸列表,然后使用 patch 函数来渲染圆。其中每个圆的前 2 个点与下一个圆对应的 2 个点组成一个正方形,然后进行渲染。
使用这样的东西:
for i=1:400
face = [(i) (i+1) (i+21) (i+20)];
patch('Faces',face,'Vertices',torus_vertices,'FaceColor','r'); %Should do this at the end
end
为此我得到了这样的东西:
3d Torus (IMG)
它扭曲并且一些侧面和内侧面被弄乱了。我认为这可能与顶点在某些时候翻转的顺序有关。
解决这个问题的最佳方法是什么?如果可能的话,我想用 surf 功能来做。
Ex1.m
%Initial positions
position = [2 0 0];
normal = [0 1 0];
%Rotation matrix
rotate18 = [cos(todeg(18)) -sin(todeg(18)) 0;
sin(todeg(18)) cos(todeg(18)) 0;
0 0 1];
% translate along the x axis by 5
translate = [5 0 0];
%% iterate 20 times to get a list of all the vertices
taurus_vertices = zeros(0, 3);
for i=0:20
%rotate translation by 18 degrees
translate = translate * rotate18;
%translate
position = position + translate;
%rotate the normal so it faces the right direction
normal = normal * rotate18;
%Get vertices for the circle and append to vertices list
circle_vertices = circle_3D(1, position, normal);
taurus_vertices = cat(1, taurus_vertices, circle_vertices);
%translate back to original position
position = position - translate;
end
%scatter3(taurus_vertices(1:end, 1), taurus_vertices(1:end, 2), taurus_vertices(1:end, 3));
%% Render each face
for i=1:400
face = [(i) (i+1) (i+21) (i+20)];
patch('Faces',face,'Vertices',taurus_vertices,'FaceColor','r');
end
圆.m
function h_circle=circle_3D(r, M, n)
%% Prepare input parameters
if size(n,2)>size(n,1)
n=n';
end
if size(M,2)>size(M,1)
M=M';
end
%% Define unit vectors u and v
% u and v define a new coordinate system in a plane perpendicular to n
a=[1;0;0];
b=[0;1;0];
if isempty(find(cross(a,n), 1))==1
a=[0;0;1];
elseif isempty(find(cross(b,n), 1))==1
b=[0;0;1];
end
alpha=dot(n,a)/dot(n,n);
u=a-alpha*n;
v=cross(u,n);%b-beta*n-gamma*u;
u=u/sqrt(sum(u.*u));
v=v/sqrt(sum(v.*v));
%% Plot the circle
hold on
axis equal
degs = 0;
points = 0;
verts = zeros(20, 3);
for phi=0: pi()/180 : 2*pi()
degs=degs+1;
if (mod(degs,18) == 0 )
points = points + 1;
verts(points,1)=M(1,1)+r*cos(phi)*u(1,1)+r*sin(phi)*v(1,1);
verts(points,2)=M(2,1)+r*cos(phi)*u(2,1)+r*sin(phi)*v(2,1);
verts(points,3)=M(3,1)+r*cos(phi)*u(3,1)+r*sin(phi)*v(3,1);
end
end
h_circle= verts;
【问题讨论】:
标签: matlab