Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Coordinates from Graphics3D images

104 views
Skip to first unread message

Russell Chipman

unread,
Mar 18, 2011, 6:59:59 AM3/18/11
to
Dear MathGroup
I am searching for a way to find the {x,y,z} coordinates at every pixel in a Graphics3D view.

I found a way to do this in ParametricPlot3D using ColorFunction, but Graphics3D does not accept ColorFunction as an option.

To get the pixels at every coordinate ParametricPlot3D view, I encode the coordinates into an RGBColor image, then recover them from the three color planes. Because the arguments to RGBColor are 0 < x < 1, first I scale all coordinates into this range. Later I unscale them.

Take the example function

ff[u_,v_]:={(2+Cos[v])Cos[u]/\[Pi],(2+Cos[v])Sin[u]/\[Pi],Sin[v]}

and the view

ParametricPlot3D[ff[u,v],{u,0,2\[Pi]},{v,0,2 \[Pi]},ViewPoint->{4,-4,8}]

My scaling and unscaling utilities need the maximum and minimum coordinates as inputs

squeeze[x_,min_,max_]:=(x-min)/(max-min)
unsqueeze[fx_,min_,max_]:=fx (max-min)+min

Now I can get an list with each pixel's {x,y,z} as

xyz=Map[unsqueeze[#,-1,1]&,ImageData[Image[ParametricPlot3D[ff[u,v],{u,0, 2\[Pi]},{v,-\[Pi]/2,\[Pi]/2},
ColorFunction->Function[{x,y,z},Glow[RGBColor[squeeze[x,-1,1],squeeze[y,-1, 1],squeeze[z,-1,1]]]],
ColorFunctionScaling->False,ViewPoint->{4,-4,8},Mesh->False,Boxed->False,Axes->False,Background->Black]]],{2}];

Now, for example, you can print the pixel coordinates or view the points in 3D with a function like

Graphics3D[Map[{Hue[(#[[3]]+1)/2],Point[#]} &,xyz[[ ;; ;;10, ;; ;;10,All]],{2}]]

My question is if there is a method for Graphics3D which can recover pixel coordinates with a similar result?

Thank you,
Russell Chipman

Fred Klingener

unread,
Mar 19, 2011, 6:17:55 AM3/19/11
to
On Mar 18, 6:59 am, Russell Chipman <rchip...@optics.arizona.edu>
wrote:

> Dear MathGroup
> I am searching for a way to find the {x,y,z} coordinates at every pixel in a Graphics3D view.
>
> I found a way to do this in ParametricPlot3D using ColorFunction, but Graphics3D does not accept ColorFunction as an option.
>
> To get the pixels at every coordinate ParametricPlot3D view, I encode the coordinates into an RGBColor image, then recover them from the three color planes. Because the arguments to RGBColor are 0 < x < 1, first I scale all coordinates into this range. Later I unscale them.
>
> Take the example function
>
> ff[u_,v_]:={(2+Cos[v])Cos[u]/\[Pi],(2+Cos[v])Sin[u]/\[Pi],Sin[v]}
>
> and the view
>
> ParametricPlot3D[ff[u,v],{u,0,2\[Pi]},{v,0,2 \[Pi]},ViewPoint->{4,-4,8}]

As nifty as your approach is, the easy way to get the nodes for this
surface is to look at the structure:

pp3D= ParametricPlot3D[ff[u,v],{u,0,2\[Pi]},{v,0,2 \[Pi]},ViewPoint-
>{4,-4,8}]

pp3D is a GraphicsComplex, and you can browse the structure with
something like

Pane[
FullForm[
pp3D]
, Scrollbars -> {False, True}
, ImageSize -> {300, 300}
]

(I don't know why Mathematica doesn't have a ScrollForm)

The first argument of the GraphicsComplex is a list of the points on
the surface, and you can retrieve them with

Graphics3D[
Point[
points=
Cases[
pp3D
, GraphicsComplex[pt__, ___] :> pt
, Infinity
]
]
]

Most of Mathematica's 3D structures can be dissected this way, and if
you need the connectivity, look at the list of primitives pp3D//Normal
produces. For example, you can get all the isolated Polygons with

Graphics3D[
polygons=
Cases[
pp3D // Normal
, _Polygon
, Infinity
]

or the mesh lines (if you specified meshing in the original.)

Graphics3D[
lines=
Cases[
pp3D // Normal
, _Line
, Infinity
]
]

Hth,
Fred Klingener

finkh

unread,
Mar 19, 2011, 6:18:27 AM3/19/11
to
There is a section in the Mathematica Cookbook: 7.11 Constructing
Wireframe Models from Mesh that may be of assistance. Also
http://blog.wolfram.com/2009/09/11/twisted-architecture/

Heike Gramberg

unread,
Mar 19, 2011, 7:17:35 AM3/19/11
to
If you're using mathematica 8 and your 3D object consists of polygons, you =
could use Texture. You would get the same effect as the ColorFunction in Pa=
rametricPlot3D when you take the texture data to be a suitable 3-dimensiona=
l matrix and the VertexTexturCoordinates of your Graphics3D object equal to=
its (scaled) vertex coordinates. There is an example in basic examples sec=
tion in the documentation for VertexTextureCoordinates where they do exactl=
y that. From there on I guess you can use the same functions as before.

Heike


On 18 Mar 2011, at 10:59, Russell Chipman wrote:

> Dear MathGroup
> I am searching for a way to find the {x,y,z} coordinates at every pixel i=
n a Graphics3D view.
>
> I found a way to do this in ParametricPlot3D using ColorFunction, but Gra=


phics3D does not accept ColorFunction as an option.
>

> To get the pixels at every coordinate ParametricPlot3D view, I encode the=
coordinates into an RGBColor image, then recover them from the three color=
planes. Because the arguments to RGBColor are 0 < x < 1, first I scale al=


l coordinates into this range. Later I unscale them.
>
> Take the example function
>

> ff[u_,v_]:=={(2+Cos[v])Cos[u]/\[Pi],(2+Cos[v])Sin[u]/\[Pi],Sin[v]}


>
> and the view
>
> ParametricPlot3D[ff[u,v],{u,0,2\[Pi]},{v,0,2 \[Pi]},ViewPoint->{4,-4,8}]
>

> My scaling and unscaling utilities need the maximum and minimum coordinat=
es as inputs
>
> squeeze[x_,min_,max_]:==(x-min)/(max-min)
> unsqueeze[fx_,min_,max_]:==fx (max-min)+min


>
> Now I can get an list with each pixel's {x,y,z} as
>

> xyz==Map[unsqueeze[#,-1,1]&,ImageData[Image[ParametricPlot3D[ff[u,v],{u,0=


, 2\[Pi]},{v,-\[Pi]/2,\[Pi]/2},

> ColorFunction->Function[{x,y,z},Glow[RGBColor[squeeze[x,-1,1],squeeze[y,-=


1, 1],squeeze[z,-1,1]]]],

> ColorFunctionScaling->False,ViewPoint->{4,-4,8},Mesh->False,Boxed->False,=


Axes->False,Background->Black]]],{2}];
>

> Now, for example, you can print the pixel coordinates or view the points=


in 3D with a function like
>

> Graphics3D[Map[{Hue[(#[[3]]+1)/2],Point[#]} &,xyz[[ ;; ;;10, ;; ;;10,All]=
],{2}]]
>
> My question is if there is a method for Graphics3D which can recover pixe=

finkh

unread,
Mar 30, 2011, 5:10:29 AM3/30/11
to
I would like to extract the surface and the accompanying texture from

moon = SphericalPlot3D[1, {u, 0, Pi}, {v, 0, 2 Pi}, Mesh -> None,
TextureCoordinateFunction -> ({#5, 1 - #4} &),
PlotStyle ->
Directive[Specularity[White, 10],
Texture[Import[
"http://finkh.files.wordpress.com/2011/03/ldem_4.png"]]],
Lighting -> {"Ambient", White}, Axes -> False, Boxed -> False,
RotationAction -> "Clip"]

This is a map of the moon with elevation data represented by a
grayscale texture taken from the Planetary Data System. When I
extract the polygons from the object the texture does not travel with
the polygons. How would I select a portion of the sphere while
preserving the shape and the texture.

Then reorient so the center of the selection is up, convert to
cartesian, listplot3d and export as stl for the rapid prototyper.

Here is what I am doing: http://finkh.wordpress.com/2011/02/01/the-south-pole-of-the-moon-shackleton-crater/

Heike Gramberg

unread,
Mar 31, 2011, 7:04:43 AM3/31/11
to
The Texture just adds a layer of paint, i.e. it doesn't change the shape of you object.
You mention that you want to export it to stl. I'm not familiar with the format but
according to the Mathematica documentation it doesn't save colour, so texture
wouldn't be saved either.

Another approach to get something that looks like the first picture in your example
is make a ListPlot3D of the grey level data and then transform the coordinates in
your plot to cartesian coordinates using replacement rules.

What I mean is something like

(*importing data*)data = N[Rescale[Import["ldem_4.png", "Data"]]];
data = Join[data, data[[All, {1}]],
2];(*for periodicity purposes*)(*sector of interest*)
thetaRange = \
{30 Degree, 90 Degree};
phiRange = {25 Degree, 60 Degree};
sector = Take[data,
Round[Rescale[thetaRange, {0., Pi}, {1, Dimensions[data][[1]]}]],
Round[Rescale[phiRange, {0., 2 Pi}, {1, Dimensions[data][[2]]}]]];

(*for transforming to cartesian coordinates*)
dr = 0.1;(*max elevation relative to radius of the moon*)

pt[{ph_, th_, e_}] := {Sin[th] Cos[ph], Sin[th] Sin[ph], Cos[th]} (1 + dre);
rotMat = RotationMatrix[{pt[{Total[phiRange]/2, Total[thetaRange]/2,
1}], {0, 0, 1}}]; (* rotating the center of the sector *)

(*plot in spherical coordinates*)

plot = ListPlot3D[sector, DataRange -> {phiRange, thetaRange},
Mesh -> None, NormalsFunction -> None];

(*transformation to cartesian coordinates*)

sphPlot =
Release[plot /.
GraphicsComplex[a_, c__] ->
GraphicsComplex[Hold[rotMat.pt[#] & /@ a], Hold[c]]];
Show[sphPlot, PlotRange -> All]

Heike

0 new messages