11

I made a polygon with the following vertexes :

p = {{0, 0, 0}, {0, 0, 300}, {0, 300, 300}, {0, 300, 0}};(*Vertices of the polygon*)
myGraphics=Graphics3D[{Polygon[p]}, Boxed -> False, Lighting -> {Gray}];

How can I find the vertexes of myGraphics?

rm -rf
  • 88,781
  • 21
  • 293
  • 472
subbu
  • 2,304
  • 1
  • 13
  • 32
  • You mean you want to "see" the coordinates of the vertexes from the polygon myGraphics? If so, try InputForm@myGraphics. – xzczd Nov 02 '12 at 05:51
  • Sorry, I need to nitpick this! It's vertices, not vertexes. – Joren Nov 02 '12 at 11:04
  • please remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign` – chris Nov 02 '12 at 13:42
  • @Joren I thought so too but FWIW Wikipedia says vertexes is acceptable... – Yves Klett Nov 02 '12 at 20:18
  • @Joren, both "vertices" and "vertexes" are acceptable (as with "indexes" and "indices"); "vertexes" discomfits me personally, but that's more of a stylistic than a grammatical complaint. – J. M.'s missing motivation Nov 03 '12 at 01:38
  • @Joren I started editing the post to change them to vertices, and in fact, changed most of them before I realized that my browser was not highlighting them in red. To me, reading "Vertexes" is like hearing chalk scratch on the board. However, it is a valid word and an equivalent of vertices... :( – rm -rf Nov 03 '12 at 01:46

3 Answers3

14

Try the following:

In[2]:= Cases[myGraphics, Polygon[pts_] -> pts, Infinity]
Out[2]= {{{0, 0, 0}, {0, 0, 300}, {0, 300, 300}, {0, 300, 0}}}

If your Graphics3D object had many polygons you would get a list comprised of lists of the vertexes of all of them.

Update

In response to István Zachar's commentL: to confine the pattern to match only 3D polygons, use

Cases[myGraphics, Polygon[pts:{{_,_,_}..}] -> pts, Infinity]
m_goldberg
  • 107,779
  • 16
  • 103
  • 257
11

A function to extract graphics primitives:

ClearAll[getVrtxCoords];
getVrtxCoords[plot_, prims : {___}] := Module[{pts, pts2,
   prms = Alternatives @@ prims,
vcoords = Cases[plot, GraphicsComplex[{coords___}, __] :> {coords}, {0, Infinity}]},
pts = Cases[plot, prms[points : {({_, _} | {_, _, _}) ..}, ___] :> points, {0, 
 Infinity}];
If[vcoords === {},
If[pts === {}, {}, First@pts],
If[(pts2 =  Cases[plot, prms[{points___}, ___] :> 
   ((First[vcoords][[#]]) & /@ {points}), {0, Infinity}]) == {}, {}, First@pts2]]]

Examples:

(* OP's example : *)
p = {{0, 0, 0}, {0, 0, 300}, {0, 300, 300}, {0, 300, 0}};
myGraphics =  Graphics3D[{Polygon[p]}, Boxed -> False, Lighting -> {Gray}];
Grid[{{"image", "Points", "Lines", "Polygons"},
   Prepend[Column[N[getVrtxCoords[myGraphics, {#}]]] & /@ 
  {Point, Line, Polygon},  myGraphics]},  Spacings -> {1, 1}, Dividers -> All]

enter image description here

A 2D example with GraphicsComplex:

 v = Table[15 {Cos[t], Sin[t]}, {t, 0, 4 Pi, 4 Pi/5}];
grphcs2 = Graphics[GraphicsComplex[v, {Red, Thick, Polygon[{1, 2, 3, 4, 5, 6}],
 Blue, Opacity[.7], Polygon[{{1, 2, 3}, {3, 4, 5}},
  VertexColors -> {{Yellow, Yellow, Yellow}, {Blue, Blue, Blue}}],
 Opacity[1], Dashed, Thickness[.02], Brown, Line[{1, 4, 2}],
 PointSize[Large], Red, Point[{1, 2, 3, 4, 5}]}]];
Grid[{{"image", "Points", "Lines", "Polygons"},
  Prepend[Column[N[getVrtxCoords[grphcs2, {#}]]] & /@
    {Point, Line, Polygon}, grphcs2]},   Spacings -> {1, 1}, Dividers -> All]

enter image description here

A 3D example:

v3 = PolyhedronData["Dodecahedron", "VertexCoordinates"];
Short[i = PolyhedronData["Dodecahedron", "FaceIndices"]];
dodec = Graphics3D[{Yellow, GraphicsComplex[v3, Polygon[i]]}, ImageSize -> 300];
modifieddodec =  Graphics3D[{Opacity[.8], EdgeForm[Opacity[.3]], 
 Polygon[#, VertexColors -> Table[Hue[RandomReal[]], {25}]] & /@ 
  getVrtxCoords[dodec, {Polygon}]}, Lighting -> "Neutral",  ImageSize -> 300];
Grid[{{"image", "reconstructed", "Points", "Lines", "Polygons"}, 
   {dodec, modifieddodec,  N@getVrtxCoords[dodec, {Point}], 
    N@getVrtxCoords[dodec, {Line}], 
    Short[N@getVrtxCoords[dodec, {Polygon}], 10]}}, Spacings -> {1, 1},
 Dividers -> All, Alignment -> {Center, Top}]

enter image description here

kglr
  • 394,356
  • 18
  • 477
  • 896
9

Another version using pattern matching which can be quite useful for other purposes as well (other than in @m_goldberg's patent solution, all points will be returned in one list, the primitive structure will not be preserved):

Cases[myGraphics, {x_?NumericQ, y_?NumericQ, z_?NumericQ}, Infinity]
{{0, 0, 0}, {0, 0, 300}, {0, 300, 300}, {0, 300, 0}}

Why is that approach (esp. the pattern) useful? You can easily work on the coordinates and it works on several important Graphics3D primitives (Point, Line, Polygon,Text) out of the box regardless of the structure of your expression. Apart from the {x,y,z} tuples your expression is not changed.

myGraphics /. {x_?NumericQ, y_?NumericQ, z_?NumericQ} :> {x, 2 y-z, 3 z}

For multi-primitive syntax, GraphicsComplex etc. this approach works as well if you get a bit more fancy on the pattern side.

Yves Klett
  • 15,383
  • 5
  • 57
  • 124