From: Peter Breitfeld on 28 Mar 2010 07:56 At school one normally uses a parallel-projection to visualize 3D Objects. I wrote some routines to map 3D-coordinates to 2D using the transformation proj[{x_,y_,z_}]:={y-x/2,z-x/2} But this doesn't work for all kind of 3D-objects. At the moment I can use my routines to map objects build of Point[], Line[] and Polygon[] primitives. My problems are: If the graphic to be mapped contains a GraphicsComplex, the display-options (color, thickness,...) go away. So I tried to use GeometricTransform, but it seems to me, that only transformations 3D->3D or 2D->2D are possible. So my question: Is it possible to have routines, which will work on any kind of 3D-primitives including Cuboid[], Cylinder[] etc, which will preserve Thickness, Color etc Thanks in advance Peter -- _________________________________________________________________ Peter Breitfeld, Bad Saulgau, Germany -- http://www.pBreitfeld.de
From: Mark McClure on 29 Mar 2010 06:21 On Sun, Mar 28, 2010 at 7:55 AM, Peter Breitfeld <phbrf(a)t-online.de> wrote: > I wrote some routines to map 3D-coordinates to 2D using the > transformation > proj[{x_,y_,z_}]:={y-x/2,z-x/2} > > But this doesn't work for all kind of 3D-objects. > ... > So my question: Is it possible to have routines, which will work on any > kind of 3D-primitives including Cuboid[], Cylinder[] etc, which will > preserve Thickness, Color etc I'd suggest that you use patterns to write a different version of proj for each primitive that you want to work with. Thus, you might have some lines like the following. proj[{x_?NumericQ, y_?NumericQ, z_?NumericQ}] := {y - x/2, z - x/2}; proj[list_List] := proj /@ list; proj[Point[pts_]] := Point[proj[pts]]; proj[Line[x_]] := Line[proj[x]]; proj[Arrow[x_]] := Arrow[proj[x]]; proj[Polygon[x_, pOpts___]] := Polygon[proj[x], pOpts]; To deal with something like Cylinder or Cuboid, you'll need to translate it two an appropriate 2D primitive to represent the projection. You might deal with a Cuboid like so Needs["ComputationalGeometry`"]; proj[Cuboid[{xmin_, ymin_, zmin_}, {xmax_, ymax_, zmax_}]] := Module[{}, vv = Tuples[{{xmin, xmax}, {ymin, ymax}, {zmin, zmax}}]; projected = proj[vv]; Polygon[projected[[ConvexHull[projected]]]]]; proj[Cuboid[{xmin_, ymin_, zmin_}]] := proj[Cuboid[{xmin, ymin, zmin}, {xmin + 1, ymin + 1, zmin + 1}]]; At the end of it all, include proj[x_] := x; to ignore everything else, such as Graphics directives. Here's an example that might or might not illustrate the idea. pic3D = Graphics3D[primitives = { {Thick, Line[{{{0, 0, 0}, {1, 1, 1}}, {{1, 0, 0}, {0, 1, 1}}, {{0, 1, 0}, {1, 0, 1}}, {{0, 0, 1}, {1, 1, 0}}}]}, {Opacity[0.5], Cuboid[{1/4, 1/4, 1/4}, {3/4, 3/4, 3/4}]}}]; pic2D = Graphics[proj[primitives]]; GraphicsRow[{pic3D, pic2D}] Dealing with GraphicsComplex is easier in some ways. Since it has the form GraphicsComplex[points, primitives] you simply map proj onto the points. But you'll need to extract Cuboids, Cylinders, Spheres and such (perhaps using Cases) to deal with them separately. Hope that helps, Mark McClure
From: dh on 29 Mar 2010 06:20 Hi Peter, the function "Normal" will change a GraphicsComplex to an expression with coordinates given explicitely. E.g.: v = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; GraphicsComplex[v, Polygon[{1, 2, 3, 4}]] // FullForm gives: GraphicsComplex[List[List[1,0],List[0,1],List[-1,0],List[0,-1]],Polygon[List[1,2,3,4]]] but: v = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; GraphicsComplex[v, Polygon[{1, 2, 3, 4}]] // Normal // FullForm gives: List[Polygon[List[List[1,0],List[0,1],List[-1,0],List[0,-1]]]] Daniel On 28.03.2010 13:56, Peter Breitfeld wrote: > At school one normally uses a parallel-projection to visualize 3D > Objects. I wrote some routines to map 3D-coordinates to 2D using the > transformation > > proj[{x_,y_,z_}]:={y-x/2,z-x/2} > > But this doesn't work for all kind of 3D-objects. At the moment I can > use my routines to map objects build of Point[], Line[] and Polygon[] > primitives. > > My problems are: If the graphic to be mapped contains a > GraphicsComplex, the display-options (color, thickness,...) go away. > > So I tried to use GeometricTransform, but it seems to me, that only > transformations 3D->3D or 2D->2D are possible. > > So my question: Is it possible to have routines, which will work on any > kind of 3D-primitives including Cuboid[], Cylinder[] etc, which will > preserve Thickness, Color etc > > Thanks in advance > Peter > -- Daniel Huber Metrohm Ltd. Oberdorfstr. 68 CH-9100 Herisau Tel. +41 71 353 8585, Fax +41 71 353 8907 E-Mail:<mailto:dh(a)metrohm.com> Internet:<http://www.metrohm.com>
From: Peter Breitfeld on 30 Mar 2010 06:02 With the help of dh and Mark I'm now near to what I wanted. My definitions are: Definitions of the projection of some primitives: Clear[SBProj] SBProj[{x_?NumericQ, y_?NumericQ, z_?NumericQ}] :={y - x/2, z - x/2}; SBProj[ll_List] := SBProj /@ ll; SBProj[Point[pts_]] := Point[SBProj[pts]]; SBProj[Line[x_]] := Line[SBProj[x]]; SBProj[Arrow[x_]] := Arrow[SBProj[x]]; SBProj[Polygon[x_, opts___]] := Polygon[SBProj[x], opts]; SBProj[x_] := x; Transforming a 3D to a 2D graphic: Clear[SBGraph]; SBRule = { Point[x_] :> SBProj[Point[x]], Line[x_] :> SBProj[Line[x]], Arrow[x_] :> SBProj[Arrow[x]], Polygon[x_, opts___] :> SBProj[Polygon[x, opts]]}; SBGraph[gr_] := Module[{pr = gr[[1]]}, If[Head[pr] === GraphicsComplex, pr = pr //. GraphicsComplex[x_, y__] :> Normal[GraphicsComplex[x, y]]]; pr = DeleteCases[pr, Rule[VertexNormals, _], Infinity]; pr /. SBRule] I think I had to Delete the VertexNormals options, because 2D-Polynoms don't like this option My routine to show the graphic: Clear[SBZeichne] Options[SBZeichne] = Options[Graphics]; SetOptions[SBZeichne, Axes -> True, AspectRatio -> Automatic]; SBZeichne[ grSB_List, {xmin_, xmax_, dx_: 2}, {ymin_, ymax_, dy_: 1}, {zmin_, zmax_, dz_: 1}, dd_: 0.6, opt : OptionsPattern[]] := Module[{t, xSc, xLL, ySc, yLL, zSc, zLL, optA}, optA = OptionValue[Axes]; xSc = {}; xLL = {}; ySc = {}; yLL = {}; zSc = {}; zLL = {}; If[optA == True, xSc = Table[{Line[{t = SBProj[{i, 0, 0}], t + {-0.07, 0}}], Text[Style[ToString[i], FontSize -> 9], t, {-2, 0.5}]}, {i, Ceiling[xmin], Floor[xmax], dx}]; xSc = DeleteCases[xSc, Text[_, {0, 0}, __], \[Infinity]]; xLL = Arrow[{SBProj[{xmin, 0, 0}], SBProj[{xmax + 2 dd, 0, 0}]}]; ySc = Table[{Line[{{i, 0}, {i, 0.07}}], Text[Style[ToString[i], FontSize -> 9], {i, 0}, {0, 1.2}]}, {i, Ceiling[ymin], Floor[ymax], dy}]; ySc = DeleteCases[ySc, Text[_, {0, 0}, __], \[Infinity]]; yLL = Arrow[{{ymin, 0}, {ymax + dd, 0}}]; zSc = Table[{Line[{{0, i}, {-0.07, i}}], Text[Style[ToString[i], FontSize -> 9], {0, i}, {-2, 0}]}, {i, Ceiling[zmin], Floor[zmax], dz}]; zSc = DeleteCases[zSc, Text[_, {0, 0}, __]]; zSc = DeleteCases[zSc, Text[_, {0, 0}, __], \[Infinity]]; zLL = Arrow[{{0, zmin}, {0, zmax + dd}}]; ]; Show[Graphics[{grSB, xLL, xSc, yLL, ySc, zLL, zSc}], Axes -> False, PlotRange -> {{Min[ymin, -(xmax + 2 dd)/2.], Max[ymax + dd, -xmin/2.]}, {Min[zmin, -(xmax + 2 dd)/2.], Max[zmax + dd, -xmin/2]}}, Flatten[{opt, Options[SBPlot]}]] ] This works fine for all examples which aren't GraphicsComplex, e.g.: This works fine, including Thickness and Color: test = Graphics3D[{Thick, Blue, Line[{{{0, 0, 0}, {1, 1, 1}}, {{1, 0, 0}, {0, 0, 1}}, {{0, 1, 0}, {1, 0, 1}}, {{0, 0, 1}, {1, 1, 0}}}]}]; SBZeichne[SBGraph[test], {0, 1, 1}, {0, 1}, {0, 1}, 0.2] This one too: p = ParametricPlot3D[{Cos[t], Sin[t], t/(2 \[Pi])}, {t, 0, 8 \[Pi]}, PlotStyle -> {Blue, Thickness[0.02]}]; SBZeichne[SBGraph[p], {0, 1}, {0, 2}, {0, 4.1}] But, this one (a GraphicsComplex) shows the plane, but only in black with some white Mesh-lines. I hoped to be able to preserve the Mesh and (blue) coloring from the original Graphics3D[GraphicsComplex] when displaying it with SBZeichne: gr = Plot3D[x + y, {x, -2, 2}, {y, -2, 2}]; SBZeichne[SBGraph[gr], {0, 5}, {0, 5}, {0, 5}] What am I missing or doing wrong? Thanks for your help Peter Mark McClure wrote: > On Sun, Mar 28, 2010 at 7:55 AM, Peter Breitfeld <phbrf(a)t-online.de> wrote: >> I wrote some routines to map 3D-coordinates to 2D using the >> transformation >> proj[{x_,y_,z_}]:={y-x/2,z-x/2} >> >> But this doesn't work for all kind of 3D-objects. >> ... >> So my question: Is it possible to have routines, which will work on any >> kind of 3D-primitives including Cuboid[], Cylinder[] etc, which will >> preserve Thickness, Color etc > > I'd suggest that you use patterns to write a different version of proj > for each primitive that you want to work with. Thus, you might have > some lines like the following. > > proj[{x_?NumericQ, y_?NumericQ, z_?NumericQ}] := {y - x/2, z - x/2}; > proj[list_List] := proj /@ list; > proj[Point[pts_]] := Point[proj[pts]]; > proj[Line[x_]] := Line[proj[x]]; > proj[Arrow[x_]] := Arrow[proj[x]]; > proj[Polygon[x_, pOpts___]] := Polygon[proj[x], pOpts]; > > To deal with something like Cylinder or Cuboid, you'll need to > translate it two an appropriate 2D primitive to represent the > projection. You might deal with a Cuboid like so > > Needs["ComputationalGeometry`"]; > proj[Cuboid[{xmin_, ymin_, zmin_}, {xmax_, ymax_, zmax_}]] := > Module[{}, > vv = Tuples[{{xmin, xmax}, {ymin, ymax}, {zmin, zmax}}]; > projected = proj[vv]; > Polygon[projected[[ConvexHull[projected]]]]]; > proj[Cuboid[{xmin_, ymin_, zmin_}]] := proj[Cuboid[{xmin, ymin, zmin}, > {xmin + 1, ymin + 1, zmin + 1}]]; > > At the end of it all, include > > proj[x_] := x; > > to ignore everything else, such as Graphics directives. Here's an > example that might or might not illustrate the idea. > > pic3D = Graphics3D[primitives = { > {Thick, Line[{{{0, 0, 0}, {1, 1, 1}}, {{1, 0, 0}, {0, 1, 1}}, > {{0, 1, 0}, {1, 0, 1}}, {{0, 0, 1}, {1, 1, 0}}}]}, > {Opacity[0.5], Cuboid[{1/4, 1/4, 1/4}, {3/4, 3/4, 3/4}]}}]; > pic2D = Graphics[proj[primitives]]; > GraphicsRow[{pic3D, pic2D}] > > Dealing with GraphicsComplex is easier in some ways. Since it has the form > > GraphicsComplex[points, primitives] > > you simply map proj onto the points. But you'll need to extract > Cuboids, Cylinders, Spheres and such (perhaps using Cases) to deal > with them separately. > > Hope that helps, > Mark McClure > -- _________________________________________________________________ Peter Breitfeld, Bad Saulgau, Germany -- http://www.pBreitfeld.de
|
Pages: 1 Prev: A general problem with numerical functions defined Next: Multi-dimensional Fourier series |