问题
I trying to color a surface known only by its corner according to its Y value with Mayavi. Original, I I succeed in making the same thing with matplotlib (here) but I put back this canonical on my real data, the rendering was not sufficient and therefore I am trying now with Mayavi. I found the example from Surface from irregular data example which is quite helpful. However when applied to my case, reproduce here on this simple case, the triangulation gets wrong as seen on the figure below for the left surface, with two lower triangles instead of an upper and a lower triangle as for the right surface.
I figure out that it came from the position of the second Y-vertices however I want to find a more general solution to 1) avoid this wrongful triangulation and 2) to have a more smooth surface by interpolating between each corner like in my previous post and avoid as much as possible thus the fold seen on the right surface, due to the splitting of my surface in only two triangles. Any ideas about doing this with Mayavi?
Here is the code I used to generate this simple example:
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import numpy
from mayavi import mlab
X1 = numpy.array([0, 0, 1, 1])
Y1 = numpy.array([0.5, 0.75, 1, 0.5])
Z1 = numpy.array([0, 1, 0.5,0])
X2 = numpy.array([0, 0, 1, 1])
Y2 = numpy.array([-0.5, -0.45, -1, -0.5])
Z2 = numpy.array([0, 1, 0.5,0])
fig = mlab.figure(1, bgcolor=(1, 1, 1), fgcolor=(0.5, 0.5, 0.5))
# Building the working triangulation
# Define the points in 3D space
# including color code based on Z coordinate.
pts = mlab.points3d(X1, Y1, Z1, Y1, colormap='jet')
# Triangulate based on X, Y with Delaunay 2D algorithm.
# Save resulting triangulation.
mesh = mlab.pipeline.delaunay2d(pts)
# Remove the point representation from the plot
pts.remove()
# Draw a surface based on the triangulation
surf = mlab.pipeline.surface(mesh, colormap='jet')
# Building the buggus triangulation
pts = mlab.points3d(X2, Y2, Z2, Y2, colormap='jet')
# Triangulate based on X, Y with Delaunay 2D algorithm.
# Save resulting triangulation.
mesh = mlab.pipeline.delaunay2d(pts)
# Remove the point representation from the plot
pts.remove()
# Draw a surface based on the triangulation
surf = mlab.pipeline.surface(mesh, colormap='jet')
# Simple plot.
mlab.outline(extent=(0,1,-1,1,0,1))
mlab.axes(extent=(0,1,-1,1,0,1), nb_labels=3)
mlab.show()
回答1:
You are using different arrays
compared to your matplotlib example.
matplotlib example:
z = numpy.array([0, **0.5, 1,** 0])
here:
Z1 = numpy.array([0, **1, 0.5**,0])
With the correct z
array the plot looks similar to your matplotlib example, including interpolation to get a smoother color transition.
回答2:
The function mlab.pipeline.delaunay2d
computes a 2D Delaunay triangulation of the set of points. That means that the triangles that are created depend only on the X and Y coordinates of the points, ignore the Z.
The two different triangulations you get are the awaited ones, as far as I have understood. Maybe there was a typo in your second data set, and that would explain why you are surprised. Did you meant the following?
X2 = numpy.array([0, 0, 1, 1])
Y2 = numpy.array([-0.5, -0.75, -1, -0.5])
Z2 = numpy.array([0, 1, 0.5,0])
The difference is the second coordinate of Y2
which is -0.75
instead of -0.45
.
来源:https://stackoverflow.com/questions/20979274/bad-automatic-triangulation-with-mayavi-for-coloring-a-surface-known-only-by-its