Thanks. By the way, very interesting topic those voronoi diagrams. May be tricky to apply in 3d. Isn’t there really a simpler way to do it?
I guess, there needs to be an imaginary plane, and then, try to cast from each point on the shape.
But, can do an imaginary plane like this? And more important, how can i check if an object is inside the shape?
ArrayList<Point> finalPoints = new ArrayList<Point>();
for (int i = 0; i < width; i ++){
for (int j = 0; j < height; j++ ){
int z = 0
while (!z = 0){
is Point(x,y, z) in the shape ?
yes -> save into ArrayList and break;
no -> z ++
}
}
}
The idea is that it just gives you a top down view. In the example I’ve provided I am in fact recommended to start with cones which are drawn in 3d and then the whole perspective is rotated so the camera is top down. So everything looks circular
If all you want is a bitmap image with grayscale mapping then no need for casting nor 2d projection. You could just colorize the faces of your mesh based on the depth of their vertices (either y or z value depending on the orientation of your original mesh) and the color value of your background.
With Processing:
load your ‘obj’ file with loadShape()
iterate over the vertices of your mesh to find the deepest and highest ones
convert your mesh to a PShape object with createShape()
while doing so, map the depth of each vertex against a color range starting from 0 (black) to the chosen background color (up to 255).
important: depending on the topology of your shape you may want to opt for a non-linear interpolation (circular, exponential or else)
save the final output with saveFrame()
A quick example (Python mode) with exponential interpolation:
the higher the exponent (from 2 to 9), the better the blend with the background
W, H = 700, 900 #Dimensions of canvas
BGC = 200 #Background color value
P = 6 #Exponent value
def setup():
perspective(60 * DEG_TO_RAD, W/float(H), 2, 6000)
translate(W>>1, H>>1)
background(BGC)
size(W, H, P3D)
noStroke()
global miny, maxy
obj = loadShape('Skull.obj') #Load mesh object
miny, maxy = get_YBounds(obj) #Get min/max height values
shp = to_PShape(obj) #Convert mesh (obj) to PShape
#Move shape in front of camera + display
translate(0, 11, 740)
rotate(PI)
rotateX(-HALF_PI*.9)
shape(shp)
#Save output
saveFrame('output.png')
def to_PShape(s):
'''Traverse the selected mesh and construct a PShape object from its faces/vertices'''
shp = createShape(GROUP)
for child in s.getChildren():
face = createShape()
face.beginShape(QUAD)
for i in xrange(child.getVertexCount()):
v = child.getVertex(i)
c = map(v.y**P, miny**P, maxy, 0, BGC)
face.fill(c)
face.vertex(v.x, v.y, v.z)
face.endShape()
shp.addChild(face)
return shp
def get_YBounds(s):
'''Traverse the selected mesh and get the min/max height values'''
vals = []
for child in s.getChildren():
for i in xrange(child.getVertexCount()):
v = child.getVertex(i)
vals.append(v.y)
vals = sorted(vals)
return vals[0], vals[-1]
I am having some problems with running your code, probably because I cannot focus the obj in the middle of screen, but will work on it I will also refractor the code later into Java, just for future regeneration.
It surprises me how little is on the internet in this topic. Especially in form of code. Your method is the same that Blender uses. I additionally found TerreSculptor which does the job.