Skip to Main Content Skip to Search
Product Documentation

plot::SurfaceSettriangle and quad surface meshes

plot::SurfaceSet(MeshList) creates a 3D graphical object from a given list of triangle or quad coordinates.

→ Examples

Call:

plot::SurfaceSet(meshlist, <MeshListType = t>, <MeshListNormals = n>, <UseNormals = b>, <a = amin .. amax>, Options)

Parameters:

meshlist

the point list: a list of coordinates of type DOM_FLOAT.
meshlist is equivalent to the attribute MeshList.

Options:

MeshListType = t

t may be Triangles, TriangleFan, TriangleStrip, Quads or QuadStrip. This attribute specifies the kind of surface mesh given in MeshList. This means it specifies how the point coordinates in MeshList are to be interpreted.

MeshListNormals = n

n may be None, BeforePoints, BehindPoints, BeforeFacets or BehindFacets. This attribute specifies whether MeshList contains normal vectors and at which positions they are located.

UseNormals = b

b may be TRUE or FALSE. This attribute specifies whether the normals defined in the STL file are used for the MuPAD® plot.

Related Domains:

plot::Rotate3d, plot::Scale3d, plot::Surface, plot::SurfaceSTL, plot::Transform3d, plot::Translate3d

Related Functions:

plot, readbytes

Details:

Example 1

When given a list of real numbers, plot::SurfaceSet by default considers them as the coordinates of points in 3D forming triangles. Note that we are using FillColorFunction here to make the triangles easier to see and that the number of values must be divisible by 9, since each triangle needs 9 numbers to be specified:

plot(plot::SurfaceSet([frandom() $ i = 1..9*5],
  FillColorFunction = (i -> RGB::ColorList[floor((i+2)/3)]))):

MuPAD graphics

Example 2

This examples demonstrates how surface sets can be created and animated in MuPAD. First we create a mesh of points:

delete cx, cy, cz, r:
F:= [[[cx-r  ,cy-r+a,cz+r], [cx-r+a,cy-r  ,cz+r],
      [cx+r-a,cy-r  ,cz+r], [cx+r  ,cy-r+a,cz+r],
      [cx+r  ,cy+r-a,cz+r], [cx+r-a,cy+r  ,cz+r],
      [cx-r+a,cy+r  ,cz+r], [cx-r  ,cy+r-a,cz+r]],
     [[cx+r,cy-r  ,cz-r+a], [cx+r,cy-r+a,cz-r  ],
      [cx+r,cy+r-a,cz-r  ], [cx+r,cy+r  ,cz-r+a],
      [cx+r,cy+r  ,cz+r-a], [cx+r,cy+r-a,cz+r  ],
      [cx+r,cy-r+a,cz+r  ], [cx+r,cy-r  ,cz+r-a]],
     [[cx-r  ,cy+r,cz-r+a], [cx-r+a,cy+r,cz-r  ],
      [cx+r-a,cy+r,cz-r  ], [cx+r  ,cy+r,cz-r+a],
      [cx+r  ,cy+r,cz+r-a], [cx+r-a,cy+r,cz+r  ],
      [cx-r+a,cy+r,cz+r  ], [cx-r  ,cy+r,cz+r-a]]]:

F:= F.[subs(F[1], cz+r=cz-r),
       subs(F[2], cx+r=cx-r),
       subs(F[3], cy+r=cy-r)]:

T:= [[cx+r,cy-r+a,cz+r], [cx+r-a,cy-r,cz+r], [cx+r,cy-r,cz+r-a]]:
T:= T.subs(T, cx+r-a=cx-r+a, cx+r=cx-r):
T:= T.subs(T, cy-r+a=cy+r-a, cy-r=cy+r):
T:= T.subs(T, cz+r-a=cz-r+a, cz+r=cz-r):

Then we create plot objects using the mesh above:

cx := 0: cy := 0: cz := 0:
r := 1:
P := range ->
  plot::Group3d(
    plot::Group3d(
        plot::SurfaceSet(map(F[i], op), a = range,
                         MeshListType = TriangleFan)
        $ i=1..6),
    plot::Group3d(
        plot::Polygon3d(F[i], a = range, Closed) $ i=1..6,
        LineWidth = 1.5,
        LineColor = RGB::Grey,
        PointsVisible,
        PointSize = 3),
      plot::Group3d(
        plot::SurfaceSet(map(T, op), a = range),
        FillColorType = Flat,
        FillColor=RGB::Yellow,
        Filled)
  ):

plot(P(0..r),
     Scaling = Constrained,
     Width = 120, Height = 120,
     Axes = None):

MuPAD graphicsimage

The first half of this animation is plotted again. In the left image we can see how parts of the surface set are constructed as triangle fan. In the right image parts of the surface are displayed as wireframe:

plot(
  plot::Scene3d(P(0..r/2), MeshVisible = TRUE),
  plot::Scene3d(P(0..r/2), Filled = FALSE),
  Scaling = Constrained, Width = 150, Height = 75,
  Axes = None, Layout = Horizontal
):

MuPAD graphicsimage

Example 3

A second animation demonstrates the fold back of a cube:

r := 1:
bottom := [[0, 0, 0], [r, 0, 0],
           [r, r, 0], [0, r, 0]]:
left   := [[0, 0, 0], [0, -r*sin(a), r*cos(a)],
           [r, -r*sin(a), r*cos(a)], [r, 0, 0]]:
right  := map(left, l -> [l[1], r-l[2], l[3]]):
front  := map(left, l -> [l[2], l[1], l[3]]):
back   := map(right, l -> [l[2], l[1], l[3]]):
top    := [left[3], left[2],
           zip(left[2], [0, -r*sin(2*a-PI/2), r*cos(2*a-PI/2)], `+`),
           zip(left[3], [0, -r*sin(2*a-PI/2), r*cos(2*a-PI/2)], `+`)]:

plot(plot::SurfaceSet(map(bottom.left.top.right.front.back, op),
                      MeshListType = Quads,
                      PointsVisible = TRUE,
                      PointSize = 3,
                      MeshVisible = TRUE,
                      LineWidth = 1.5,
                      LineColor = RGB::Grey,
                      a=0..PI/2),
     plot::MuPADCube(Radius = r/3, Center = [r/2 $ 3]),
     Scaling = Constrained)

MuPAD graphicsimage

delete r, bottom, left, right, front, back, top:

Example 4

Let's have a deeper look on the different kind of mesh types. We create a mesh of points first and then plot it using the different mesh types available. The first point will always be plotted in red color:

PL:= [((0,i,0.5-0.1*i), (1,i,0.5-0.1*i)) $ i = 0..5]:
SO:= FillColorFunction =
     ((n,x,y,z)->[RGB::Blue,RGB::Red,RGB::Green][(n mod 3)+1]),
     LineColorFunction =
     ((n,x,y,z)-> if n=1 then RGB::Red else RGB::Black end_if),
     PointsVisible:
VO:= plot::Camera([0.5,2.5,4.5], [0.5,2.51,0], 0.2),
     ViewingBox = [0..1,0..5,0..0.5],
     Axes = None:

We tell MuPAD® to interpret the given mesh list as a set of separate triangles. The corresponding plot looks like this:

plot(plot::SurfaceSet(PL, SO, MeshListType = Triangles), VO):

MuPAD graphics

We tell MuPAD to interpret the given mesh list as a triangle fan. The corresponding plot looks like this:

plot(plot::SurfaceSet(PL, SO, MeshListType = TriangleFan), VO):

MuPAD graphics

The plot above looks a little bit confusing, thus we let MuPAD plot the first four triangles step by step in order to learn how the whole fan will be created:

plot(
  plot::Scene3d(
    plot::SurfaceSet(PL[1..3*n], SO, MeshListType = TriangleFan),
    VO
  ) $ n=3..6
):

MuPAD graphics

We tell MuPAD to interpret the given mesh list as a triangle strip. The corresponding plot looks like this:

plot(plot::SurfaceSet(PL, SO, MeshListType = TriangleStrip), VO):

MuPAD graphics

We tell MuPAD to interpret the given mesh list as a set of separate quads. The corresponding plot looks like this:

plot(plot::SurfaceSet(PL, SO, MeshListType = Quads), VO):

MuPAD graphics

The reason for plotting triangles instead of (the expected) rectangles is the order of the points in the point list. Changing the order of the second and third point, we get the expected result:

PK:= PL: tmp:= PK[7]: PK[7]:= PK[10]: PK[10]:=tmp:
plot(plot::SurfaceSet(PK, SO, MeshListType = Quads), VO):
delete PK, tmp:

MuPAD graphics

We tell MuPAD to interpret the given mesh list as a quad strip. The corresponding plot looks like this:

plot(plot::SurfaceSet(PL, SO, MeshListType = QuadStrip), VO):
delete PL, SO, VO:

MuPAD graphics

Example 5

It is possible to include normals to give smooth shading for surfaces that are not supposed to look like flat triangles. In the following example, we use a triangulation of a rectangle:

trias := [([x,  y   ], [(x+1), y], [ x   ,(y+1)],
           [x, (y+1)], [(x+1), y], [(x+1),(y+1)])
         $ x = 1..4 $ y = 1..4]:

Mapping the function (x, y) -> sin(x)*cos(y) to these points, we get the following surface plot:

f := (x,y) -> sin(x)*cos(y):
meshList := map(trias, l -> [l[1], l[2], f(l[1], l[2])]):
plot(plot::SurfaceSet(meshList, MeshListType = Triangles))

MuPAD graphics

The triangulation is clearly visible. One way to reduce this would be to refine the mesh, but this may take a lot of time with more complicated functions or be completely impossible for measurement data. It is much faster to give MuPAD more information on the surface, namely, the direction of the tangent planes at the points we evaluated:

normals  := map(trias, l -> [D([1], f)(l[1], l[2]),
                             D([2], f)(l[1], l[2]), 1]):
plot(plot::SurfaceSet(zip(meshList, normals, _exprseq),
                      MeshListType = Triangles,
                      MeshListNormals = BehindPoints))

MuPAD graphics

As you can see (especially at the border; otherwise, switch on LinesVisible), MuPAD still draws the triangles at exactly the same places, but uses a color shading to create the illusion of a smooth surface.

Example 6

We create a triangle mesh with normals in front of each triangle and plot this object, a tetrahedron, afterwards:

meshList:= [
   0.0 ,  0.0 , -1.0 ,
  -1.5 , -1.5 ,  1.4 ,  0.0,  1.7, 1.4, 1.5, -1.5,  1.4,
   0.0 ,  0.88,  0.47,
  -1.5 , -1.5 ,  1.4 ,  1.5, -1.5, 1.4, 0.0,  0.0, -1.4,
  -0.88, -0.41,  0.25,
   1.5 , -1.5 ,  1.4 ,  0.0,  1.7, 1.4, 0.0,  0.0, -1.4,
   0.88, -0.41,  0.25,
   0.0 ,  1.7 ,  1.4 , -1.5, -1.5, 1.4, 0.0,  0.0, -1.4
]:
plot(
  plot::SurfaceSet(meshList,
        MeshListType    = Triangles,
        MeshListNormals = BeforeFacets
  )
):

MuPAD graphics

Example 7

A color function FillColorFunction can be specified. The procedure is called for each vertex: the parameters are the index of the current triangle followed by the x-, y- and z-coordinate of the current vertex:

plot(
  plot::Scene3d(
    plot::SurfaceSet(meshList, MeshListNormals = BeforeFacets,
      MeshVisible = TRUE,
      LineColor    = RGB::Black,
      FillColorFunction =
      (n ->[RGB::Red,RGB::Blue,RGB::Green,RGB::Yellow]
             [n+2 div 3])
    )
  ),
  plot::Scene3d(
    plot::SurfaceSet(meshList, MeshListNormals = BeforeFacets,
      MeshVisible = TRUE,
      LineColor    = RGB::Black,
      FillColorFunction = ((n,x,y,z) -> [x/2,y/2,z/2])
    )
  ),
  Axes = None, Layout = Horizontal
):

MuPAD graphics

The same is true for a LineColorFunction:

plot(
  plot::Scene3d(
    plot::SurfaceSet(meshList, MeshListNormals = BeforeFacets,
      MeshVisible  = TRUE,
      PointsVisible = TRUE,
      Filled        = FALSE,
      LineWidth     = 2,
      LineColorFunction =
      (n -> [RGB::Red,RGB::Blue,RGB::Green,RGB::Yellow][n+2 div 3])
    )
  ),
  plot::Scene3d(
    plot::SurfaceSet(meshList, MeshListNormals = BeforeFacets,
      MeshVisible  = TRUE,
      PointsVisible = TRUE,
      Filled        = FALSE,
      LineWidth     = 2,
      LineColorFunction = ((n,x,y,z) -> [x/4,y/4,z/4])
    )
  ),
  Axes = None, Layout = Horizontal
):

MuPAD graphics

Example 8

Again we plot the object defined in example 6, but now we add a rotated, scaled and translated copy of it:

plot(
  plot::Scene3d(
    plot::SurfaceSet(meshList, MeshListNormals = BeforeFacets),
    plot::Scale3d([2,2,2],
      plot::SurfaceSet(meshList, MeshListNormals = BeforeFacets,
                       Color = RGB::Blue.[0.1])
    )
  ),
  plot::Scene3d(
    plot::SurfaceSet(meshList, MeshListNormals = BeforeFacets),
    plot::Rotate3d(PI, Axis=[1,0,0],
      plot::SurfaceSet(meshList, MeshListNormals = BeforeFacets,
                        Color = RGB::Blue.[0.1])
    )
  ),
  plot::Scene3d(
    plot::SurfaceSet(meshList, MeshListNormals = BeforeFacets),
    plot::Translate3d([1,1,1],
      plot::SurfaceSet(meshList, MeshListNormals = BeforeFacets,
                        Color = RGB::Blue.[0.1])
    )
  ),
  plot::Scene3d(
    plot::SurfaceSet(meshList, MeshListNormals = BeforeFacets),
    plot::Transform3d([0,0,0], [1,0,0, 0,1,0, 0,0,-1],
      plot::SurfaceSet(meshList, MeshListNormals = BeforeFacets,
                        Color = RGB::Blue.[0.1])
    )
  ),
  Width = 120, Height = 120
):

MuPAD graphics

Background:

The normal of a facet (a triangle or quad) given in MeshList is used for all its vertices when plotting this object. Due to the fact that some facets may share points with other facets, these points may be specified with different normals.

  


Recommended Products

Includes the most popular MATLAB recorded presentations with Q&A sessions led by MATLAB experts.

 © 1984-2012- The MathWorks, Inc.    -   Site Help   -   Patents   -   Trademarks   -   Privacy Policy   -   Preventing Piracy   -   RSS