Re: Incorrect, misleading, "Operate Directly on Graphics" example.
- To: mathgroup at smc.vnet.net
- Subject: [mg80952] Re: Incorrect, misleading, "Operate Directly on Graphics" example.
- From: "Eric W. Weisstein" <eww at wolfram.com>
- Date: Thu, 6 Sep 2007 05:26:56 -0400 (EDT)
- References: <fblji3$pji$1@smc.vnet.net>
Well, look at the default output of PolyhedronData. It uses the new GraphicsComplex structure introduced in V6 to efficiently handle graphics with shared coordinates: In[1]:= PolyhedronData["Cube"] // InputForm Out[1]//InputForm= Graphics3D[GraphicsComplex[{{-1/2, -1/2, -1/2}, {-1/2, -1/2, 1/2}, {-1/2, 1/2, -1/2}, {-1/2, 1/2, 1/2}, {1/2, -1/2, -1/2}, {1/2, -1/2, 1/2}, {1/2, 1/2, -1/2}, {1/2, 1/2, 1/2}}, Polygon[{{8, 4, 2, 6}, {8, 6, 5, 7}, {8, 7, 3, 4}, {4, 3, 1, 2}, {1, 3, 7, 5}, {2, 1, 5, 6}}]]] See the Documentation Center for more details on both PolyhedronData and GraphicsComplex. You can operate on this structure directly using something like: PolyhedronData["Cube"] /. p_Polygon :> {Yellow, Opacity[.3], p} (note that your Polygon[x : {_, _, _}] replacement rule doesn't work here because it doesn't match the structure of the Polygon inside the GraphicsComplex), or you can use PolyhedronData to just return the GraphicComplex itself without the Graphics3D wrapper and then operate on that yourself: Graphics3D[{Yellow, Opacity[.3], PolyhedronData["Cube", "Faces"]}] or you can use Normal to expand the GraphicsCompex into individual Polygon's: Normal[PolyhedronData["Cube"]] /. p_Polygon :> {Yellow, Opacity[.3], p} Note that your rule Polygon[x : {_, _, _}] still will not match because it still doesn't match Polygon[{{1/2, 1/2, 1/2}, ...}] (i.e., a standalone Polygon takes nested coordinate lists of 2 or 3 elements as an argument). However, after Normal'ing, you could then do something like: Normal[PolyhedronData["Cube"]] /. Polygon[x : {{_, _, _} ..}] :> {Yellow, Opacity[.3], Polygon[x]} Normal[PolyhedronData["Cube"]] /. Polygon[x_List] :> {Yellow, Opacity[. 3], Polygon[x]} Normal[PolyhedronData["Cube"]] /. Polygon[x_List?MatrixQ] :> {Yellow, Opacity[.3], Polygon[x]} Normal[PolyhedronData["Cube"]] /. Polygon[x__List] :> {Yellow, Opacity[.3], Polygon[x]} etc. So there are really many ways to do this in Mathematica, depending on your application and what is convenient for you. Some might be slightly more efficient than others for large, complicated graphics. (Also note that PolyhedronData in general gives analytic values for coordinates, so if you're doing complicated things with them, there might be circumstances where you would want to numericize them first.) Hope that helps, -Eric On Sep 5, 1:49 am, "Q.E.D." <a... at netzero.net> wrote: > I looked at another example, "Operate Directly on Graphics". > It's off the "New in 6" "Dynamic Graphical Input" page, the top right image, > the small/large polyhedrons. > URL:http://www.wolfram.com/products/mathematica/newin6/content/DynamicGra... > > This looks so neat, just apply a simple rule and you get this > change...except you don't. > > Here's what I tried -- input and evaluate: > > PolyhedronData["SnubDodecahedron"] > > Then cut and paste the graphics object and append: > > /. Polygon[x : {_, _, _}] :> {Yellow, Opacity[.3], Polygon[x]} > > Nothing happens, the resulting graphics object is unchanged. > > So I dug around a bit and came up with a graphics object which is of the > form (a list of polygons) expected by the rule: > > Graphics3D[ > Map[Polygon, > PolyhedronData["SnubDodecahedron", "VertexCoordinates"][[#]] & /@ > PolyhedronData["SnubDodecahedron", "FaceIndices"]]] > > Now cut and paste this special graphics object and again append the rule > given by the "Operate Directly on Graphics" example: > > /. Polygon[x : {_, _, _}] :> {Yellow, Opacity[.3], Polygon[x]} > > And, yes it works, giving the graphics object shown as output by the > example. > > So how do you get this result just using the plain graphics object from > PolyhedronData["SnubDodecahedron"]? > > Here's what I ended up with as a rule: > > /.Polygon[x_] :> {Polygon[Cases[x, Except[{_, _, _}]]], > {Yellow, Opacity[.3], Polygon[Cases[x, {_, _, _}]]}} > > The complexity is necessary due to the way the plain graphics object is > structured. > It keeps an array of shared vertex coordinates and a single polygon object > with a list of index lists into that array. > So the rule breaks the polygon object into two parts, one without triangles > the other with only triangles and the change applied. > This keeps the graphics object small and allows the change to be made > rapidly. > > Q.E.D.