我正在写一个代码来生产一个给定的高度,宽度,长度和倾斜屋顶的角度的房子。
我可以使用surf对特定的尺寸使用零值来生成墙,允许将墙制作为x-y平面、x-z平面等。
然而,现在我正在尝试制作一张桌子,里面是一个有特定高度的x-y平面,但我想不出是怎么做到的。
MATLAB说它需要一个矩阵,但仅由高度组成的矩阵不起作用,使用ndgrid(heightValue:.5:heightValue)也不起作用
如果有人知道如何帮助我,我将不胜感激。
代码:
(对于类似的问题,办公桌一侧也在错误的位置,但帮助解决此问题将使我能够弄清楚如何修复它)
clear; clc; close all;
%% INPUT VARIABLES
lengthdlg = 'Please enter length of base (m): ';
widthdlg = 'Please enter width of base (m): ';
heightdlg = 'Please enter height of wall (m): ';
angledlg = 'Please enter the angle of the roof (degrees): ';
dlgbox = inputdlg({lengthdlg, widthdlg, heightdlg, angledlg},...
'Simple AutoCAD', [1 50; 1 50; 1 50; 1 50], {'30','40','15','30'});
BaseL = str2double(dlgbox(1));
BaseW = str2double(dlgbox(2));
WallH = str2double(dlgbox(3));
RoofA = str2double(dlgbox(4));
m = tand(RoofA);
h = figure;
set(h,'name','Simple AutoCAD House','numbertitle','off')
xlabel('x'),ylabel('y'),zlabel('z')
title('Simple AutoCAD House')
colormap white
%% Base/Floor
[xB,yB] = ndgrid(0:1:BaseL, 0:1:BaseW);
zB = (xB*0);
surf(xB,yB,zB,'FaceColor','k')
hold on
%% Walls
%Front Wall (w/Door opening)
[xFW,zFW] = ndgrid(0:1:BaseL, 0:1:WallH);
yFW = (xFW*0);
yFW(xFW>.4*BaseL & xFW<.6*BaseL & zFW<.8*WallH) = nan;
surf(xFW,yFW,zFW);
hold on
%Back Wall
[xBW,zBW] = ndgrid(0:.5:BaseL, 0:.5:WallH);
yBW = (xBW*0)+BaseW;
surf(xBW,yBW,zBW);
%Right Wall
[yRW,zRW] = ndgrid(0:.5:BaseW, 0:.5:WallH);
xRW = (yRW*0)+BaseL;
surf(xRW,yRW,zRW);
%Left Wall
[yLW,zLW] = ndgrid(0:.5:BaseW, 0:.5:WallH);
xLW = (yLW*0);
xLW(yLW>.25*BaseW & yLW<.75*BaseW & zLW>.5*WallH & zLW<.7*WallH) = nan;
surf(xLW,yLW,zLW);
%% Roof
%Left Panel
[xLP,yLP] = ndgrid(0:.5:(BaseL/2), 0:.5:BaseW);
zLP = (m*xLP)+WallH;
surf(xLP,yLP,zLP)
hold on
%Right Panel
[xRP,yRP] = ndgrid((BaseL/2):.5:BaseL, 0:.5:BaseW);
zRP = (-m*xRP)+(WallH+m*BaseL);
surf(xRP,yRP,zRP)
%% Roof Triangles
%Front Triangle
[xFT,zFT] = ndgrid(0:.25:BaseL, WallH:.25:(m*BaseL/2)+WallH);
yFT = 0*xFT;
yFT(zFT>(m*xFT+WallH)) = nan;
yFT(zFT>(-m*xFT+(m*BaseL+WallH))) = nan;
surf(xFT,yFT,zFT)
%Back Triangle
[xBT,zBT] = ndgrid(0:.25:BaseL, WallH:.25:(m*BaseL/2)+WallH);
yBT = (xBT*0)+BaseW;
yBT(zBT>(m*xBT+WallH)) = nan;
yBT(zBT>(-m*xBT+(m*BaseL+WallH))) = nan;
surf(xBT,yBT,zBT)
%% Door
[xD,zD] = ndgrid(.4*BaseL:.5:.6*BaseL, 0:.5:.8*WallH);
yD = xD*0;
door = surf(xD,yD,zD,'FaceColor','g');
%% Windows
%Left Window
[yLWin,zLWin] = ndgrid(.25*BaseW:.5:.75*BaseW, .5*WallH:.5:.75*WallH);
xLWin = (yLWin*0);
surf(xLWin,yLWin,zLWin,'FaceAlpha',.25,'FaceColor','b')
%% Desk and chair
%desktop
[xDT,yDT] = ndgrid(.8*BaseL:.5:.99*BaseL, .7*BaseW:.5:.99*BaseW);
zDT = (0*xDT);
surf(xDT,yDT,zDT,'FaceColor','r')
%DeskNear
[xDN,zDN] = ndgrid(.8*BaseL:.5:BaseL, 0:.5:.25*WallH);
yDN=(0*zDN)
surf(xDN,yDN,zDN,'FaceColor','r')
%% Door Opening
k = waitforbuttonpress;
if k == 0
delete(door)
end发布于 2016-03-24 12:46:06
曲面的ZData特性是曲面中每个点的z坐标。在您的示例中,您通过将其设置为与XData和YData相同的大小来将其设置为正确的大小;但是,您构造ZData的方式有点不对劲。您实际上是这样做的:
zDT = (0 * xDT);这实际上是强制网格中每个点的z坐标为0(即在地板上)。这就是为什么桌面只是简单地放在地板上,也是为什么桌子的一侧放在墙上(y = 0)的原因。
要解决这个问题,您需要计算这些值的实际值,而不是将它们设置为零。
桌面
好的是,整个桌面的z值实际上是整个表面的常量,因为它与地面平行。您可以在创建桌面侧面时定义桌面的高度。
[xDN, zDN] = ndgrid(.8*BaseL:.5:BaseL, 0:.5:.25*WallH);这里你说的是桌子的高度是0.25 * WallH四舍五入到前面的0.5 (因为你的步长)。因此,我们希望将桌面的ZData设置为该值(zDN的最大值),然后将该值乘以XData的大小为1的矩阵,以使其大小合适。
zDT = max(zDN(:)) * ones(size(xDT));办公桌侧面
在办公桌的另一边,问题不再是ZData,而是YData。就像现在一样,你将它设置为全零,这样它就会被挂在y = 0的墙上。
yDN = (0 * zDN);同样,我们希望整个桌子的y值都是恒定的。我们可以通过使用桌面上的最小y值来计算y值(同样,通过使用1的矩阵来确保它的大小是正确的)。
yDN = min(yDT(:)) * ones(size(xDN));摘要
我们可以对这两个部分进行修改,这会使代码的底部看起来像这样。
%desktop
[xDT,yDT] = ndgrid(.8*BaseL:.5:.99*BaseL, .7*BaseW:.5:.99*BaseW);
[xDN,zDN] = ndgrid(.8*BaseL:.5:BaseL, 0:.5:.25*WallH);
zDT = max(zDN(:)) * ones(size(xDT));
surf(xDT,yDT,zDT,'FaceColor','r')
%DeskNear
yDN = min(yDT(:)) * ones(size(xDN));
surf(xDN,yDN,zDN,'FaceColor','r')如果我们应用这一点,我们就可以将桌面从地板和桌面的一侧移到它属于的地方。

正如Amro在对你的帖子的评论中所说的那样,使用patch而不是surf来绘制这类东西可能要容易得多,因为它在形状方面给了你更大的灵活性。
发布于 2016-03-24 12:57:35
这是我对房子的描述:)
代码应该很容易理解。请注意,我使用的是patch函数。
% input measurements
BaseL = 30;
BaseW = 40;
WallH = 15;
RoofA = 30;
% colors
m = tand(RoofA);
clr = hsv(10);
clf
% floor
patch([0 1 1 0].*BaseL, ...
[0 0 1 1].*BaseW, ...
[0 0 0 0].*WallH, clr(1,:));
% front wall (w/ door opening)
patch([1 1 0 0 0.4 0.4 0.6 0.6].*BaseL, ...
[0 0 0 0 0 0 0 0].*BaseW, ...
[0 1 1 0 0 0.8 0.8 0].*WallH, clr(2,:));
% back wall
patch([0 1 1 0].*BaseL, ...
[1 1 1 1].*BaseW, ...
[0 0 1 1].*WallH, clr(3,:));
% right wall
patch([1 1 1 1].*BaseL, ...
[0 0 1 1].*BaseW, ...
[0 1 1 0].*WallH, clr(4,:));
% left wall (w/ window opening)
patch([0 0 0 0 0 0 0 0 0 0 0 0].*BaseL, ...
[0 0 0.5 0.5 0.25 0.25 0.75 0.75 0.5 0.5 1 1].*BaseW, ...
[0 1 1 0.7 0.7 0.5 0.5 0.7 0.7 1 1 0].*WallH, clr(5,:));
% roof left/right panels
patch([0 0.5 0.5 0].*BaseL, ...
[0 0 1 1].*BaseW, ...
[0 1 1 0].*(m*BaseL/2)+WallH, clr(6,:));
patch([1 0.5 0.5 1].*BaseL, ...
[0 0 1 1].*BaseW, ...
[0 1 1 0].*(m*BaseL/2)+WallH, clr(7,:));
% roof front/back triangles
patch([0 1 0.5].*BaseL, ...
[0 0 0].*BaseW, ...
[0 0 1].*(m*BaseL/2)+WallH, clr(8,:));
patch([0 1 0.5].*BaseL, ...
[1 1 1].*BaseW, ...
[0 0 1].*(m*BaseL/2)+WallH, clr(9,:));
% door
hDoor = patch([0.4 0.6 0.6 0.4].*BaseL, ...
[0 0 0 0].*BaseW, ...
[0 0 0.8 0.8].*WallH, 'k', 'FaceAlpha',0.75);
% window on left wall
hWin = patch([0 0 0 0].*BaseL, ...
[0.25 0.75 0.75 0.25].*BaseW, ...
[0.5 0.5 0.7 0.7].*WallH, 'k', 'FaceAlpha',0.75);
% table inside
patch([0.8 0.99 0.99 0.8].*BaseL, ...
[0.7 0.7 0.99 0.99].*BaseW, ...
[0.2 0.2 0.2 0.2].*WallH, clr(10,:));
patch([0.8 0.99 0.99 0.8].*BaseL, ...
[0.7 0.7 0.7 0.7].*BaseW, ...
[0.01 0.01 0.2 0.2].*WallH, clr(10,:));
patch([0.8 0.99 0.99 0.8].*BaseL, ...
[0.99 0.99 0.99 0.99].*BaseW, ...
[0.01 0.01 0.2 0.2].*WallH, clr(10,:));
% 3D view
axis([0 BaseL 0 BaseW 0 WallH*2]), axis vis3d
view(3), grid on
xlabel('X'), ylabel('Y'), zlabel('Z')
title('Simple AutoCAD House')
% animate door/window transparencies
t = linspace(-pi,pi,20);
anim = @(t) 1-(tanh(t)+1)/2; % smooth function from 1 to 0
for i=1:numel(t)
set([hDoor,hWin], 'FaceAlpha',anim(t(i)))
pause(0.1)
end

在最后有一个小动画,门和窗从有色变为透明。希望你会喜欢!
https://stackoverflow.com/questions/36191910
复制相似问题