New Graphics Features in Mathematica

Chris Calson and Yuzhu Lu
Wolfram Research, Inc.

New 2D/3D Graphics Features for V8:

Texture

JoinedCurve and FilledCurve

Arrow of Curves

Inset3D

Multi-Transformation

Multi-Arrow

3D Transparency Rendering Improvement

Drawing Tools

Alignment Guides

New Interactive Operations

New Syntax

Usabilty Improvements

Texture

KeyWords:  ▪ Texture . VertexTextureCoordinates . Polygon   . FaceForm . Plot3D

Texture mapping have been added to the new version of Mathematica for both 2D and 3D polygons.

Manipulate[Graphics[{Texture[],Polygon[{{1,1},{3,1},{1+2a,3}},VertexTextureCoordinates->{{0,1},{1,1},{a,0}}]}],{a,0,1}]

v={{-1,-1,-1},{1,-1,-1},{1,1,-1},{-1,1,-1},{-1,-1,1},{1,-1,1},{1,1,1},{-1,1,1}};
i={{1,2,3,4},{1,2,6,5},{2,3,7,6},{3,4,8,7},{4,1,5,8},{5,6,7,8}};
t={{0,0},{0,1},{1,1},{1,0}};
box=;
Graphics3D[{Texture[box],Black,GraphicsComplex[v,Polygon[i,VertexTextureCoordinates->{t,t,t,t,t,t}]]}]

ParametricPlot[r^2{ Sqrt[t]Cos[t], Sin[t]},{t,0,3Pi/2},{r,1,2},PlotStyle->{Opacity[1],Texture[]},Axes->False,Frame->False]

ParametricPlot3D[{Cos[u] Sin[v],Sin[u] Sin[v],Cos[v]} ,{u, 0, 2π}, {v, 0, π},Background->Black,Axes->False,Mesh->None,Boxed->False,SphericalRegion->True,Lighting->{{"Ambient",White}},PlotStyle->Texture[]]

2 Sided Texture

i2={{1,4,3,2},{1,2,6,5},{2,3,7,6},{3,4,8,7},{4,1,5,8}};
box=;
checker=Graphics[{Polygon[Join@@Table[{{i,j},{i+1,j},{i+1,j+1},{i,j+1}},{i,0,7,2},{j,0,7,2}]],Polygon[Join@@Table[{{i,j},{i+1,j},{i+1,j+1},{i,j+1}},{i,1,8,2},{j,1,8,2}]]},PlotRange->{{0,8},{0,8}}];
Graphics3D[{FaceForm[Texture[box],Texture[checker]],Black,GraphicsComplex[v,Polygon[i2,VertexTextureCoordinates->{t,t,t,t,t}]]}]

Used as Different Materials

ParametricPlot3D[{Cos[t] (3+Cos[u]),Sin[t] (3+Cos[u]),Sin[u]},{t,0,2Pi},{u,0,2Pi},PlotStyle->{Texture[]},TextureCoordinateFunction->(0.1{#1,#2,0}+{.5,.5,0}&),Axes->False,Lighting->"Neutral",Mesh->None,Boxed->False]

ParametricPlot3D[{Cos[t] (3+Cos[u]),Sin[t] (3+Cos[u]),Sin[u]},{t,0,2Pi},{u,0,2Pi},PlotStyle->{Texture[],Specularity[White,10]},TextureCoordinateFunction->(0.1{#1,#2,0}+{.5,.5,0}&),Axes->False,Lighting->"Neutral",Mesh->None,Boxed->False]

Sky Box

Volume Rendering

JoinedCurve and FilledCurve

KeyWords:  ▪ JoinedCurve . Line . BezierCurve . BSplineCurve . Arrow

JoinedCurve

Line, BezierCurve and BSplineCurve can be used together to construct a segment.

Graphics[Curve[{Line[{{0,1},{1,1}}],BezierCurve[{{2,0.5},{1,0}}],Line[{{1,0},{0,0}}]},CurveClosed->True]]

FilledCurve

Line, BezierCurve and BSplineCurve can be used together to construct a filled region.

Graphics[FilledCurve[{Line[{{0,1},{1,1}}],BezierCurve[{{2,0.5},{1,0}}],Line[{{1,0},{0,0}}]}]]

Import/Export

FilledCurve have been used to export different styles of fonts.

First@ImportString[ExportString[Style[B,Blue,FontFamily->"Edwardian Script ITC",100],"PDF"],"TextOutlines"->True]

Arrow of Curves

KeyWords:  ▪ Arrow . Arrowheads . Graphics  . Graphics3D . Line . BezierCurve . BSplineCurve . Curve . Tube

Arrow now works for all curve versions for both 2D and 3D

2D

Arrow now works with Line[], BezierCurve[], BSplineCurve[], Curve[] in 2D case

Graphics[{Arrowheads[Table[{0.04,i},{i,0.1,1,0.1}]],Arrow[BezierCurve[{{0,0},{1,1},{2,-1}}]]}]

a={Arrowheads[Large],Arrow[Curve[BSplineCurve[{{0,0},{1,1},{2,-1}}]]]};
{Graphics[{Dashed,a}],Graphics[{Red,a}],Graphics[{Thick,a}],Graphics[{Thick,Dashed,Red,a}]}

Table[Graphics[{Arrowheads[{{.1,i}}],Arrow[BezierCurve[{{0,0},{1,-1},{2,1}}]]},PlotRange->{{-0.1,2},{-0.5,1}}],{i,{0.2,0.5,1}}]

h=Graphics[Line[{{-1,1/2},{0,0},{-1,-1/2},{-1,1/2}}]];
Graphics[{Arrowheads[{{-.1,0,{h,1}},{.1,1,{h,1}}}],Arrow[BezierCurve[{{0,0},{1,-1},{2,1}}]]}]

Table[Graphics[{Thick,Arrowheads[{{.5,1,{h,i}}}],Arrow[BezierCurve[{{0,0},{1,-1},{2,1}}]]}],{i,{0,.5,1}}]

3D

Arrow now works with Line[], BezierCurve[], BSplineCurve[], Tube[BezierCurve[]], Tube[BSplineCurve[]]

Graphics3D[{Arrowheads[Table[{0.04,i},{i,0.1,1,0.1}]],Tooltip@Arrow[BSplineCurve[{{0,0,0},{1,1,0},{2,-1,0}},VertexColors->{Red,Green,Blue},SplineClosed->True]]}]

a={Arrowheads[Large],Arrow[Tube[BSplineCurve[{{0,0,0},{1,2,2},{4,2,2}}]]]};
{Graphics3D[{Green,a}],Graphics3D[{Red,a}]}

h=Graphics3D[Line[{{-1,1/2,0},{0,0,0},{-1,-1/2,0},{-1,1/2,0}}]];
Graphics3D[{Arrowheads[{{-.1,0,{h,1}},{.1,1,{h,1}}}],Arrow[BSplineCurve[{{0,0,0},{.5,1,1},{2,1,1}}]]}]

Inset3D

KeyWords:  ▪ Inset . Text . Billboard  .  Graphics . Graphics3D

Inset3D provide a way to put 2D graphics/expressions into 3D. The 2D Graphics is always oriented to facing the view point.

Graphics3D[{Opacity[.99],Sphere[{0,-1,0},0.5],Cuboid[{{-0.25,0.5,-0.25},{0.25,1,0.25}}],Inset[Graphics[{Disk[{0,0},.25]},ImageSize->50],{0,0,0}]},PlotRange->2]

Graphics3D[{Opacity[.99],Sphere[{0,-1,0},0.5],Cuboid[{{-0.25,0.5,-0.25},{0.25,1,0.25}}],Inset[Style["Mathematica",Blue,30],{0,0,0}]},PlotRange->2]

Graphics3D[{Opacity[.99],Sphere[{0,-1,0},0.5],Cuboid[{{-0.25,0.5,-0.25},{0.25,1,0.25}}],Inset[DynamicModule[{x=0},Button[Dynamic[x],x++;EmitSound[Sound[SoundNote[]]]]],{0,0,0}]},PlotRange->2]

Application

fire={,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,};
DynamicModule[{b=First@Range[1]},{Dynamic[Graphics3D[{CapForm[None],Tube[BSplineCurve[{{0,0,-1},{0,0,5},{0,0,10},{0,0,17},{0,0,25},{0,0,32},{0,0,35}}],{20,25,26,30,26,20,16}],Inset[Image[fire[[b]],ColorSpace-> "RGB",ImageSize->200],{0,0,45}]},Boxed->False,ImageSize->{400,400},Lighting->"Neutral"]],Dynamic[If[b<31,b++,b=First@Range[1]]]}]

dust=;
DynamicModule[{pos=RandomReal[{-1,1},3],obj=Sphere[pos,.5],a=100},{Graphics3D[{Opacity[.99],EventHandler[Dynamic[{obj}],{"MouseClicked":>(obj=obj/.{Sphere[pos,.5]->Inset[Image[dust,ColorSpace-> "RGB",ImageSize->Dynamic[a]],pos]};a=50;"shot"[[2]])}]},ImageSize->400,PlotRange->2.5],Dynamic[If[0<a<600,a=a+5,(a=1;pos=RandomReal[{-1,1},3];obj=Sphere[pos,.5])]]}]

imageProcess=;
DynamicModule[{theta=0},{Graphics3D[{Tooltip[Annotation[Inset[Hyperlink[Image[imageProcess,ImageSize->Dynamic[150/Norm[{2*Cos[theta]-1,2*Sin[theta],1}]]],"paclet:guide/ImageProcessing"],{1,0,0}],"Label","Mouse"],"Image Processing"],
Inset[Tooltip[Annotation[Hyperlink[Framed[LocatorPane[{1,1}/2,Graphics[{Blue,Opacity[Dynamic[1/Norm[{2*Cos[theta],2*Sin[theta]-1,1}]]],Disk[]},ImageSize->Dynamic[150/Norm[{2*Cos[theta],2*Sin[theta]-1,1}]]]]],"paclet:guide/GraphicsInteractivityAndDrawing"],"Label","Mouse"],"Interactive Graphics"],{0,1,0}],Inset[Tooltip[Annotation[Hyperlink[Framed[Style["Plots","Title",FontSize->Dynamic[Dynamic[100/Norm[{2*Cos[theta]+1,2*Sin[theta],1}]]]]],"paclet:guide/FunctionVisualization"],"Label","Mouse"],"Mathematica Plot Functions"],{-1,0,0}],Tooltip[Annotation[Inset[Hyperlink[Framed[PieChart[{1,2,3,4},ImageSize->Dynamic[150/Norm[{2*Cos[theta],2*Sin[theta]+1,1}]]]],"paclet:guide/ChartingAndInformationVisualization"],{0,-1,0}],"Label","Mouse"],"Charting and Information Visualization"]},Boxed->False,ImageSize->{400,400},SphericalRegion->True,PlotLabel->"Please mouse over and click objects.",ViewVector->Dynamic[{{10*Cos[theta],10*Sin[theta],2},{0,0,0}}]],Dynamic[If[theta<2Pi,theta =If[MouseAnnotation[]=!="Label",theta+0.04+.02*If[Mod[theta,Pi/2]>Pi/4,Pi/2-Mod[theta,Pi/2],Mod[theta,Pi/2]],theta],theta=0]]}]

Multi-Transformations

KeyWords:  ▪ Translate . GeometricTransformation . Graphics  . Graphics3D

Both 2D/3D multiple transformations can apply to the same group of graphics

Graphics[{GeometricTransformation[Disk[],{{{0,0}},{{6,0}},{{12,0}}}]}]

Graphics3D[GeometricTransformation[Cone[{{0,0,0},{0,0,1}},.5],{{RotationMatrix[0Degree,{0,1,0}],{0,0,1}},{RotationMatrix[90Degree,{0,1,0}],{1,0,0}},
{RotationMatrix[180Degree,{0,1,0}],{0,0,-1}},{RotationMatrix[-90Degree,{0,1,0}],{-1,0,0}}}]]

Nested case

Graphics[{GeometricTransformation[{GeometricTransformation[Disk[],{{{0,0}},{{0,2}},{{2,0}},{{2,2}}}]},{{{0,0}},{{6,0}},{{12,0}}}]}]

Graphics3D[{Tooltip[GeometricTransformation[{GeometricTransformation[Sphere[],{{{0,0,0}},{{0,2,0}},{{2,0,0}},{{2,2,0}}}]},{{{-6,0,0}},{{0,0,0}},{{6,0,0}},{{12,0,0}}}]]}]

Application

Multi-Transformation could be used to optimize your application and reduce the memory consumption

Multi-Arrows

KeyWords:  ▪ Arrow . Arrowheads . Graphics  . Graphics3D . Line . BezierCurve . BSplineCurve . Curve . Tube

Multiple form of Arrow

s={{0,0},{2,1.5},{4,0}};
{Graphics[Arrow[Line[{s,s+1}]]],Graphics[Arrow[BezierCurve[{s,s+1}]]]}

s={{0,0,0},{1,2,2},{4,2,2}};
{Graphics3D[Arrow[Line[{s,s+3}]]],Graphics3D[Arrow[BSplineCurve[{s,s+3}]]]}

Application

Multi-Arrow could be used to optimize your application and reduce the memory consumption

3D Transparency Rendering Improvement

KeyWords:  ▪ DepthPeeling . BSP Tree . Graphics3DRenderingEngine  . DepthPeelingLayers . Layers . OneLayer . Color . Depth

Graphics3DRenderingEngine

1. HardwareDepthBuffer: Rendered with hardware depth buffer
2. HardwareDepthPeeling: Rendered with hardware depth peeling method
3. Bsp Tree: Sorted with BSP Tree before rendering 
4. Software: Projected and rendered as 2D graphics
5. Automatic: HardwareDepthBuffer + HardwareDepthPeeling

Since Mathematica 8, a new method depth peeling is used as the default method to avoid polygon splitting and sorting for transparency rendering if graphics card supports. Depth peeling is a hardware accelerated mullti-rendering pass method with each pass peel one layer off. Use SystemInformation to check if your graphics card support depth peeling:

Requirement

It need hardware support, for Mac and Linux which mainly covers 4 years old NVidia and ATI cards, Intel cards are not working with it at this time. For Windows, it works if your computer support shader model 3. If it is not supported, the system will go back to use BSP tree.

If[$OperatingSystem==="Windows","Optimized 3D Transparency"/.("DirectX"/.SystemInformation["Devices","GraphicsDevices"]),"Optimized 3D Transparency"/.("OnScreen"/.("OpenGL"/.SystemInformation["Devices","GraphicsDevices"]))]

Why Depth Peeling

We were using Binary Space Partitioning (BSP) Trees. it will divide polygons into small pieces and sort them at each view point.It consumes too much memory. Here is  a simple comparison between  DP and BSP: performance and rendering result

Graphics3D[Table[With[{p={i,j,k}*2},{Opacity[.5],Sphere[p]}],{i,5},{j,5},{k,5}],BaseStyle->{RenderingOptions->{"Graphics3DRenderingEngine"->"BSPTree"}}]

Graphics3D[Table[With[{p={i,j,k}*2},{Opacity[.5],Sphere[p]}],{i,5},{j,5},{k,5}]]

How to use

Graphics3D[{Blue,Cylinder[],Red,Sphere[{0,0,2}],Black,Thick,Dashed,Line[{{-2,0,2},{2,0,2},{0,0,4},{-2,0,2}}],Green,Opacity[.3],Cuboid[{-2,-2,-2},{2,2,-1}],Yellow,Opacity[1],Polygon[{{-3,-3,-2},{-3,3,-2},{3,3,-2},{3,-3,-2}}]},ImageSize->400,Method->{"RelieveDPZFighting"->True},BaseStyle->{RenderingOptions->{"Graphics3DRenderingEngine"->#}}]&/@{"HardwareDepthPeeling","BSPTree"}

With depth peeling, user can customize the number of layers to be rendered. The default value is 8 layers. The performance of depth peeling is decided by the number of layers rendered.

Manipulate[Graphics3D[{FaceForm[Green,Red],Opacity[.5],Cuboid[],Sphere[{0.5,0.5,0.5},.25]},BaseStyle->{RenderingOptions->{"DepthPeelingLayers"->Floor[ll]}}],{ll,1,4}]

With depth peeling, user can also choose to render certain layer by using OneLayer method option in either color buffer or depth buffer.

Manipulate[Graphics3D[{Yellow,Polygon[{{-3,-3,-2},{-3,3,-2},{3,3,-2},{3,-3,-2}}],Green,Cuboid[{-1.2,-1,-2},{-2,2.5,-1.4}],Red,Cuboid[{0.4,1.2,-2},{2,2,-1.2}],Blue,Cuboid[{1,0.6,-2},{0.4,0,-1}],Yellow,Cuboid[{0.2,0.2,-2},{-0.4,-0.4,-1.4}],Brown,Cuboid[{1,-1.2,-2},{0.6,-1,-0.8}]},Boxed->False,ViewAngle->0.176`,ViewPoint->{2.0134967246056807`,-2.0795497622414096`,1.752513545272587},ViewVertical->{0.12574649600958202`,-0.003953182705401612,4.960272651497622},Method->{"OneLayer"->{"Color",Floor[ll]}}],{ll,1,6}]

Manipulate[Graphics3D[{Yellow,Polygon[{{-3,-3,-2},{-3,3,-2},{3,3,-2},{3,-3,-2}}],Green,Cuboid[{-1.2,-1,-2},{-2,2.5,-1.4}],Red,Cuboid[{0.4,1.2,-2},{2,2,-1.2}],Blue,Cuboid[{1,0.6,-2},{0.4,0,-1}],Yellow,Cuboid[{0.2,0.2,-2},{-0.4,-0.4,-1.4}],Brown,Cuboid[{1,-1.2,-2},{0.6,-1,-0.8}]},Boxed->False,ViewAngle->0.176`,ViewPoint->{2.0134967246056807`,-2.0795497622414096`,1.752513545272587},ViewVertical->{0.12574649600958202`,-0.003953182705401612,4.960272651497622},Method->{"OneLayer"->{"Depth",Floor[ll]}}],{ll,1,6}]

Millions transparent polygons can be visualized with DP

Drawing Tools

Tools

Circle

Sample Style

Double-type for persistent tools.

Graphics[{FaceForm[Magenta],EdgeForm[{Blue,Thickness[.02]}],Rectangle[]},PlotRange->3]

Operations

Graphics[Table[{Hue[RandomReal[]],With[{pt=RandomReal[{0,1},{2}]},Rectangle[pt,pt+RandomReal[{0,1},{2}]]]},{5}],PlotRangePadding->1,ContentSelectable->True]

Fill and Stroke

Graphics[{
Table[{Thickness[RandomReal[{0,0.01}]],Circle[RandomReal[{0,1},2],.2]},{3}],
Table[{EdgeForm[Thickness[RandomReal[{0,0.01}]]],FaceForm[Hue[RandomReal[{0,1}]]],Disk[RandomReal[{0,1},2],.2]},{3}]
},PlotRangePadding->.2,ContentSelectable->True]

Arrowheads

Text

Points and Rectangles

Graphics[{
Rectangle[],
PointSize[.01],Red,
Point[{{0,0},{1,0},{1,1},{0,1}}]
},PlotRangePadding->1,ContentSelectable->True]

Settings

Graphics[{Red,EdgeForm[{Thickness[0.01],Magenta}],Rectangle[]},PlotRangePadding->2,ContentSelectable->True]

New Syntax

ImageSize->a->b

Graphics[Raster[Table[If[EvenQ[x+y],0,1],{x,0,100},{y,0,100}]],Frame->True]

No longer uptight about angle order in Circle and Disk.

Manipulate[
Labeled[
Graphics[Disk[{0,0},1,{0,a}],PlotRange->1.2],
Disk[{0,0},1,{0,a}]],
{a,π,-π}
]

No longer uptight about dangling commas.

Graphics[{Disk[],Rectangle[{1,1}],}]

Questions?

Setup

SetOptions[InputNotebook[],WindowSize->{1023,767}]

SetOptions[$FrontEnd,"AlignmentGuidesEnabled"->False]

SetOptions[$FrontEnd,NewPrimitiveStyle->{}]