首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用surf放置悬挂物

如何使用surf放置悬挂物
EN

Stack Overflow用户
提问于 2016-03-24 09:52:13
回答 2查看 35关注 0票数 0

我正在写一个代码来生产一个给定的高度,宽度,长度和倾斜屋顶的角度的房子。

我可以使用surf对特定的尺寸使用零值来生成墙,允许将墙制作为x-y平面、x-z平面等。

然而,现在我正在尝试制作一张桌子,里面是一个有特定高度的x-y平面,但我想不出是怎么做到的。

MATLAB说它需要一个矩阵,但仅由高度组成的矩阵不起作用,使用ndgrid(heightValue:.5:heightValue)也不起作用

如果有人知道如何帮助我,我将不胜感激。

代码:

(对于类似的问题,办公桌一侧也在错误的位置,但帮助解决此问题将使我能够弄清楚如何修复它)

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

发布于 2016-03-24 12:46:06

曲面的ZData特性是曲面中每个点的z坐标。在您的示例中,您通过将其设置为与XDataYData相同的大小来将其设置为正确的大小;但是,您构造ZData的方式有点不对劲。您实际上是这样做的:

代码语言:javascript
复制
zDT = (0 * xDT);

这实际上是强制网格中每个点的z坐标为0(即在地板上)。这就是为什么桌面只是简单地放在地板上,也是为什么桌子的一侧放在墙上(y = 0)的原因。

要解决这个问题,您需要计算这些值的实际值,而不是将它们设置为零。

桌面

好的是,整个桌面的z值实际上是整个表面的常量,因为它与地面平行。您可以在创建桌面侧面时定义桌面的高度。

代码语言:javascript
复制
[xDN, zDN] = ndgrid(.8*BaseL:.5:BaseL, 0:.5:.25*WallH);

这里你说的是桌子的高度是0.25 * WallH四舍五入到前面的0.5 (因为你的步长)。因此,我们希望将桌面的ZData设置为该值(zDN的最大值),然后将该值乘以XData的大小为1的矩阵,以使其大小合适。

代码语言:javascript
复制
zDT = max(zDN(:)) * ones(size(xDT));

办公桌侧面

在办公桌的另一边,问题不再是ZData,而是YData。就像现在一样,你将它设置为全零,这样它就会被挂在y = 0的墙上。

代码语言:javascript
复制
yDN = (0 * zDN);

同样,我们希望整个桌子的y值都是恒定的。我们可以通过使用桌面上的最小y值来计算y值(同样,通过使用1的矩阵来确保它的大小是正确的)。

代码语言:javascript
复制
yDN = min(yDT(:)) * ones(size(xDN));

摘要

我们可以对这两个部分进行修改,这会使代码的底部看起来像这样。

代码语言:javascript
复制
%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来绘制这类东西可能要容易得多,因为它在形状方面给了你更大的灵活性。

票数 1
EN

Stack Overflow用户

发布于 2016-03-24 12:57:35

这是我对房子的描述:)

代码应该很容易理解。请注意,我使用的是patch函数。

代码语言:javascript
复制
% 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

在最后有一个小动画,门和窗从有色变为透明。希望你会喜欢!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36191910

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档