Services & Resources / Wolfram Forums
-----
 /
MathGroup Archive
2007
*January
*February
*March
*April
*May
*June
*July
*August
*September
*October
*Archive Index
*Ask about this page
*Print this page
*Give us feedback
*Sign up for the Wolfram Insider

MathGroup Archive 2007

[Date Index] [Thread Index] [Author Index]

Search the Archive

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.




  • Prev by Date: Re: Slow Show/Graphics in v6.0
  • Next by Date: Re: Slow Show/Graphics in v6.0
  • Previous by thread: Re: Incorrect, misleading, "Operate Directly on Graphics" example.
  • Next by thread: Location of Error Messages (v.6)