3D Primitives & Visualization

New FE 3D features of Mathematica 7 and after

Yuzhu Lu

Wolfram Research, Inc.

New 3D Primitives

FrontEnd 3D Primitives are 3D visual components used for Mathematica functions. You can also use it directly in your study and research.

What we have before 7

Point

Line

Polygon

Sphere

Cuboid

Cylinder

Text

What is new for 7

GeometricTransformation

Cone

Tube

Arrow

Curves (BSpline, Bezier)

Tube Curves

Surface (BSpline)

More Features For 7

Antialiasing

VertexColors and VertexNormals

3D Hit testing (Mouseover and tooltip)

Multi-primitive form

Tricks to Improve Performance

Use Multi-primitive form

Select suitable tube Caps, Joins, and Tube points

Avoid putting a lot of data in Arrowheads directive within Dynamic

Place Dynamic appropriately when using GeometricTransformation

Use packed array, if you pass in a large amount of data

Do not use transparency if you don’t need it

Do not enable Antialiasing if you don’t need it

New 3D Primitives

GeometricTransformation

KeyWords:GeometricTransformation ▪  Rotate  ▪  Translate  ▪  Scale  ▪TransformationFunction  ▪  TransformationMatrix ▪  RotationTransform  ▪  TranslationTransform  ▪  ScalingTransform   ▪ AffineTransform  ▪  ReflectionTransform  ▪  ShearingTransform

Graphics3D[GeometricTransformation[Sphere[],ShearingTransform[Pi/4,{1,0,0},{0,0,1}]]]

gr={Cuboid[],AbsolutePointSize[10],Opacity[1],{Magenta,Point[{0,0,0}]},{Green,Point[{1,1,1}]}};
Graphics3D[{{Opacity[.35],Blue,gr},GeometricTransformation[{Opacity[.85],Red,gr},{{{1,0,0},{0,1,0},{0,0,1}},{.5,.5,0}}]},Boxed->False]

New 3D Primitives

Cone

KeyWords: Cone ▪ FaceForm▪ EdgeForm

Graphics3D[Cone[{{0,0,-1},{0,0,1}},1]]

{Graphics3D[{Yellow,Cone[]}],Graphics3D[{EdgeForm[Thick],Cone[]}],Graphics3D[{EdgeForm[Dashed],Cone[]}],Graphics3D[{EdgeForm[Directive[Thick,Dashed,Blue]],Orange,Cone[]}]}

Graphics3D[{FaceForm[Yellow,Blue],Cone[]},PlotRange->{{-1,1},{-.2,1},{-1,1}}]

Histogram3D[RandomReal[NormalDistribution[0,1],{500,2}],10,ChartElementFunction->"Cone"]

New 3D Primitives

Tube

KeyWords:  Tube  ▪  JoinForm  ▪CapForm  ▪ FaceForm▪ VertexColors

Graphics3D[Tube[{{0,0,0},{1,1,1}},.1]]

Graphics3D[{CapForm["Round"],Tube[{{0,0,0},{-6,4,10}},{2,1}]}]

s={{-1,-1,-1},{1,1,1}};
Table[Graphics3D[Tube[s,Scaled[i]],PlotRange->1.5],{i,{.01,.02,.04}}]

Table[Graphics3D[{CapForm[cap],Tube[{{-1,1,-1},{1,-1/2,1}},0.7]},PlotRange->2,PlotLabel->Row[{cap}],Boxed->False],{cap,{None,"Butt","Round","Square"}}]

Table[Graphics3D[{JoinForm[j],Tube[{{-1,-1,-1},{0,0,1},{1,1,-1}},0.4]},PlotRange->2,PlotLabel->Row[{j}],Boxed->False],{j,{None,"Bevel","Round","Miter"}}]

Manipulate[Graphics3D[{Tube[{{0,0,0},{1,1,1}},1]},Method->{"TubePoints"->Dynamic[p]}],{{p,3},3,100,1}]

Graphics3D[{Tube[{{0,0,0},{2,1,1}},0.1,VertexColors->{Red,Green}]}]

Grid[Table[ParametricPlot3D[{Cos[u],Sin[u],Sin[u]},{u,0,2Pi},PlotPoints->pp,PlotRange->All,MaxRecursion->mr],{mr,{0,2}},{pp,{5,10}}]]

Grid[Table[ParametricPlot3D[{Cos[u],Sin[u],Sin[u]},{u,0,2Pi},PlotPoints->pp,PlotRange->All,MaxRecursion->mr],{mr,{0,2}},{pp,{5,10}}]]/.Line[pts_,rest___]->Tube[pts,0.1,rest]

New 3D Primitives

Arrows

KeyWords:Arrow ▪  Arrowheads  ▪ Tube  ▪ Line  ▪   JoinForm  ▪CapForm▪ FaceForm ▪VertexColors ▪  VectorPlot3D

Table[Graphics3D[{Arrowheads[i],Arrow[{{0,0,0},{2,1,1}}]},PlotLabel->i],{i,{.1,.2,.4}}]

Table[Graphics3D[{Arrowheads[i],Arrow[Tube[{{0,0,0},{2,1,1}},0.02]]},PlotLabel->i],{i,{.1,.2,.4}}]

Graphics3D[{Arrowheads[{.05,.1,.1,.05}],Arrow[{{0,0,0},{2,1,1}}]}]

Graphics3D[{Arrowheads[{.05,.1,.1,.05}],Arrow[Tube[{{0,0,0},{2,1,1}}]]}]

Table[Graphics3D[{Arrowheads[{{.1,i}}],Arrow[{{0,0,0},{2,1,1}}]}],{i,{0.2,0.5,1}}]

Table[Graphics3D[{Arrowheads[{{.1,i}}],Arrow[Tube[{{0,0,0},{2,1,1}}]]}],{i,{0.2,0.5,1}}]

a={Arrowheads[Large],Arrow[{{0,0,0},{2,1,1}}]};
{Graphics3D[{Dashed,a}],Graphics3D[{Red,a}],Graphics3D[{Thick,a}],Graphics3D[{Thick,Dashed,Red,a}]}

Graphics3D[{Arrowheads[.4],Blue,Arrow[Tube[{{0,0,0},{2,1,1}},0.1,VertexColors->{Red,Blue}]]}]

h=Graphics[Line[{{-1,1/2},{0,0},{-1,-1/2},{-1,1/2}}]];
{Graphics3D[{Arrowheads[{{-.3,0},{.3,1}}],Arrow[{{0,0,0},{2,1,1}}]}],Graphics3D[{Arrowheads[{{-.3,0},{.3,1}},Appearance->"Projected"],Arrow[{{0,0,0},{2,1,1}}]}]}

g1=GraphicsBox[LineBox[{{0,1/2},{1,0},{0,-1/2},{0,1/2}}]];
g2=GraphicsBox[PolygonBox[{{0,1/2},{1,0},{0,-1/2},{0,1/2}}]];
g3=GraphicsBox[{RGBColor[1,0,0],Thickness[0.05],LineBox[{{-1,1/2},{0,0},{-1,-1/2}}]}];
g4 =GraphicsBox[{EdgeForm[{}],LineBox[{{0,1/4},{1,1/2},{1/2,0},{1,-1/2},{0,-1/4},{0,1/4}}]}];
g5=GraphicsBox[{EdgeForm[{}],PolygonBox[{{0,1/2},{1,1/2},{1,-1/2},{0,-1/2},{0,1/2},{1/4,1/4},{3/4,1/4},{3/4,-1/4},{1/4,-1/4},{1/4,1/4}}]}];
g6=GraphicsBox[{RGBColor[1,0,0],Thickness[0.25],LineBox[{{0,1/4},{1,1/2},{1/2,0},{1,-1/2},{0,-1/4},{0,1/4}},VertexColors->{RGBColor[1,0,0],RGBColor[0,1,0],RGBColor[0,0,1],RGBColor[1,0,0],RGBColor[1,1,0],RGBColor[1,0,1]}]}];

Manipulate[Graphics3D[{Arrowheads[{{-.1,0,t},{.1,1,h}}],Arrow[Line[{{0,0,0},{1,1,.9}}],.1]}],{{h,g1,"Customized headers"},{g1->"Type 1",g2->"Type 2",g3->"Type 3"}},{{t,g1,"Customized tails"},{g1->"Type 1",g2->"Type 2",g3->"Type 3",g4->"Type 4",g5->"Type 5",g6->"Type 6"}}]

g1=Graphics3D[Cone[{{-1,0,0},{0,0,0}},0.25]];
g2=Graphics3D[Cylinder[{{-1,0,0},{0,0,0}},0.25]];
g3=Graphics3D[Sphere[{0,0,0},0.25]];
g4 =Graphics3D[Line[{{-1,1/2,0},{0,0,0},{-1,-1/2,0},{-1,1/2,0}}]];
Manipulate[Graphics3D[{Arrowheads[{{-.1,0,t},{.1,1,h}}],Arrow[Tube[{{0,0,0},{1,1,.9}}],.1]}],{{h,g1,"Customized headers"},{g1->"Type 1",g2->"Type 2",g3->"Type 3"}},{{t,g1,"Customized tails"},{g1->"Type 1",g2->"Type 2",g3->"Type 3",g4->"Type 4"}}]

tree=;
Graphics3D[{Arrowheads[{{.1,1,tree}},Appearance->"Projected"],Arrow[{{0,0,0},{0,-0,0.001}}],Green,Cuboid[{-10,-10,-3},{10,10,-2.8}]}]

rw1 = Accumulate[RandomChoice[Join[IdentityMatrix[3],-IdentityMatrix[3]],40]];
rw2 = Accumulate[Table[{1,10*Random[]*RandomChoice[{1,-1}],10*Random[]*RandomChoice[{1,-1}]},{k,0,40}]];
Manipulate[Graphics3D[{color,Opacity[o],Dash,Thickness[0.004],Arrowheads[RandomChoice[{{0.04},{0.04}},n]],Arrow[Line[p]]}],{{color,Black,"Color"},{Black->"Black",Red->"Red",Green->"Green",Blue->"Blue",Yellow->"Yellow"}},{{o,1,"Opacity"},0,1,0.1},{{Dash,Thick}, {Dashing[{Large,Large}]->"Large Dash",Dashed->"Small Dash",Thick->"Without Dash"}},{{n,50,"Number of Arrowheads"},10,100,1},{{p,rw1},{rw1->"Random Walk 1",rw2->"Random Walk 2"}}]

VectorPlot3D[{x,y-2 x,z-x},{x,-3,3},{y,-3,3},{z,-3,3},VectorColorFunction->"Rainbow",VectorScale->Medium]

New 3D Primitives

Curves

KeyWords: BezierCurve  ▪ BSplineCurve  ▪BezierFunction   ▪ BSplineFunction ▪ SplineDegree ▪ SplineKnots ▪ SplineWeights ▪ SplineClosed  ▪ Tube  ▪ Line  ▪   CapForm ▪ FaceForm ▪VertexColors ▪

Manipulate[Graphics3D[{Green,Line[{{0,0,0},{0,1,0},{1,1,x},{1,0,0},{1,-1,0},{2,-1,0},{2,0,0}}],Red,PointSize[Medium],Point[{{0,0,0},{0,1,0},{1,1,x},{1,0,0},{1,-1,0},{2,-1,0},{2,0,0}}],Blue,BezierCurve[{{0,0,0},{0,1,0},{1,1,x},{1,0,0},{1,-1,0},{2,-1,0},{2,0,0}}]}],{{x,0},-1,1,.1}]

pts=30{{-1,1,0},{-.5,-1,0},{.4,-1.5,0},{2,0,0},{3.6,-1.5,0},{4.5,-1,0},{5,1,0}};
ka={0,0,0,0,1,2,3,4,4,4,4};
kb={0,0,0,0,2,2,2,4,4,4,4};
Graphics3D[{Green,Line[pts],Red,PointSize[Medium],Point[pts],Black,BSplineCurve[pts,SplineKnots->ka,SplineDegree->3],Pink,BSplineCurve[pts,SplineKnots->kb,SplineDegree->3], Blue,BSplineCurve[pts,SplineDegree->2]}]

l=BSplineCurve[{{1,1,-1},{2,2,1},{3,3,-1},{4,4,1}}];
{Graphics3D[{Dashed,l}],Graphics3D[{Pink,l}],Graphics3D[{Thick,l}],Graphics3D[{Thick,Dashed,Pink,l}]}

Graphics3D[{Tube[BezierCurve[{{0,0,0},{10,10,0},{20,0,0}},{1,3,1},VertexColors->{Red,Green,Blue}]],Line[{{0,0,0},{10,10,0},{20,0,0}}]}]

pts = {{0,0,0},{1,1,0},{1.2,2,0},{.6,1.8,0},{0,1.3,0},{-.6,1.8,0},{-1.2,2,0},{-1,1,0},{0,0,0}};
Graphics3D[{Red,Tube[BSplineCurve[pts,{.1,.1,.1,.1,.3,.1,.1,.1,.1}]],Green,Line[pts],Black,PointSize[Medium],Point[pts]}]

Graphics3D[{FaceForm[Yellow],CapForm[None],Specularity[White,50],Tube[BSplineCurve[{{0,0,0},{10,10,10},{20,5,40},{30,10,20}},5]]}]

pts=N[Table[10{u,5 Cos[u u],5 Sin[u u]},{u,1,10,.3}]];
Graphics3D[{Black,Tube[BSplineCurve[pts,5RandomReal[1,34],SplineDegree->3]],Red,Tube[BSplineCurve[pts,5RandomReal[1,34],SplineDegree->8]],
Blue,Tube[BSplineCurve[pts,5RandomReal[1,34],SplineDegree->18]],Green,Dashed,Line[pts],White,Sphere[#,.1]&/@pts},PlotRange->All]

New 3D Primitives

Surface

KeyWords: BSplineSurface▪ BSplineFunction ▪ SplineDegree ▪ SplineKnots ▪ SplineWeights ▪ SplineClosed  ▪  FaceForm ▪▪

cpts=Table[{i,j,RandomReal[{-1,1}]},{i,5},{j,5}];
b=Graphics3D[BSplineSurface[cpts]];
Show[Graphics3D[{PointSize[Medium],Red,Map[Point,cpts],Gray,Line[cpts],Line[Transpose[cpts]]}],b]

Manipulate[
DynamicModule[{ppts,spts},
Grid[{{
Dynamic[
ppts=If[sorted,SortBy[pts,Last],pts];
spts=Table[Append[#,Last[p]]&/@(First[p] cpts),{p,ppts}];
Graphics3D[{
If[mesh,
(* Draw control meshes *)
{FaceForm[],EdgeForm[Gray],Polygon[spts],Gray,Line[Transpose[spts]],Red,PointSize[Medium],Point/@spts},{}],
FaceForm[frontc,backc],Opacity[op],Specularity[White,50],
(* NURBS Surface *)
BSplineSurface[spts,SplineClosed->{False,True},SplineDegree->2,SplineKnots->{Automatic,k},SplineWeights->Table[w,{Length[pts]}]]},
PlotRange->{{-1,1},{-1,1},{0,1}},BoxRatios->{1,1,1.25},ImageSize->{400,400}]],
(* Profile curve *)
Labeled[LocatorPane[Dynamic[pts],
Dynamic[Graphics[{BSplineCurve[ppts,SplineDegree->2],Dashed,Orange,Line[ppts]},PlotRange->{{0,1},{0,1}},Frame->True,FrameTicks->None,GridLines->Automatic,GridLinesStyle->LightGray,AspectRatio->2.5,ImageSize->{100,250}]],LocatorAutoCreate->{2,∞}],Style["profile curve","Label"],Top]
}}]
],
"None"->{{pts,{{0.5,0},{0.2,0.25},{0.5,0.5},{0.8,0.75},{.5,1}}},{0,0},{1,1},ControlType->None},
Row[{
Column[{Control[{{sorted,True,"sort control points"},{True,False}}],
Control[{{mesh,False,"show control mesh"},{True,False}}]},Right],
Spacer[20],
Column[{Control[{{frontc,Yellow,"outside color"},Yellow,ImageSize->Tiny}],
Control[{{backc,Blue,"inside color"},Blue,ImageSize->Tiny}]},Right],
Spacer[20],
Column[{Control[{{op,1,"opacity"},0,1,ImageSize->Tiny}]}]
}],
AutorunSequencing->{1,3,4,5},
Initialization:>(cpts={{0,-1},{-1,-1},{-1,1},{0,1},{1,1},{1,-1}};
w={1,.5,.5,1,.5,.5};
k={0,0,0,1/4,1/2,1/2,3/4,1};)
]

More Features For 7

Antialiasing

KeyWords: Antialiasing▪  Edit > Preferences>Appearance>Graphics...

Aliasing are distortion artifacts caused by resolution limitations of display device.

Manipulate[With[{x=n,y=n,color=RGBColor[.5,.8,.2]},
Graphics[{If[slope≤1,
Table[{Lighter[color,Boole[aa](i slope-Floor[i slope])],Rectangle[{i,Floor[i slope]},{i+1,Floor[i slope]+1}],
Lighter[color,1-Boole[aa](i slope-Floor[i slope])],Rectangle[{i,Floor[i slope]+1},{i+1,Floor[i slope]+2}]},
{i,0,x-1}],Table[{Lighter[color,Boole[aa](j/slope-Floor[j/slope])],Rectangle[{Floor[j/slope],j},{Floor[j/slope]+1,j+1}],
Lighter[color,1-Boole[aa](j/slope-Floor[j/slope])],Rectangle[{Floor[j/slope]+1,j},{Floor[j/slope]+2,j+1}]},
{j,0,y-1}]],Gray,Opacity[.7],Table[Line[{{i,-.025 y},{i,1.025 y}}],{i,0,x}],Table[Line[{{-.025 x,j},{1.025 x,j}}],{j,0,y}],
Thick,RGBColor[.1,.4,.6],Opacity[.7],If[line,Line[{{0,0},If[slope<y/x,x{1,slope},y{1/slope,1}]}],Thick]},PlotRange->{{0,1.001}x,{0,1.001}y},ImageSize->{500,320}]],
{{slope,1/3,"slope"},0,4},{{slope,1/3,"slope"},{0,1/2,1/3,11/7,1,Sqrt[2],Sqrt[3],GoldenRatio,E,Pi,2^(1/3),Infinity}},
Delimiter,{{n,10,"number of pixels"},10,50,1},
Delimiter,{{aa,True,"antialiasing"},{True,False}},
{{line,True,"show idealized line",},{True,False}},
AutorunSequencing->{1,2,3}]

More Features For 7

VertexColors and VertexNormals

KeyWords:VertexColors  ▪  RGBColor▪VertexNormals ▪   Point  ▪  Polygon  ▪Tube  ▪ Line  ▪  Arrow ▪    BezierCurve  ▪ BSplineCurve  ▪

{Graphics3D[{Thick,Line[{{0,0,0},{2,1,1}},VertexColors->{Red,Green}]}],Graphics3D[{Tube[{{0,0,0},{2,1,1}},0.1,VertexColors->{Red,Green}]}],Graphics3D[{Arrowheads[.3],Green,Arrow[Line[{{0,0,0},{2,1,1}},VertexColors->{Red,Green}]]}],Graphics3D[{Arrowheads[.3],Green,Arrow[Tube[{{0,0,0},{2,1,1}},0.05,VertexColors->{Red,Green}]]}],Graphics3D[{Thick,BezierCurve[{{0,0,0},{1,1,0.5},{2,0,1}},VertexColors->{Red,Green,Blue}]}],Graphics3D[{Tube[BezierCurve[{{0,0,0},{1,1,0.5},{2,0,1}},0.05,VertexColors->{Red,Green,Blue}]]}]}

p = Accumulate[Table[{1,10*Random[]*RandomChoice[{1,-1}],10*Random[]*RandomChoice[{1,-1}]},{k,0,99}]];
Graphics3D[{Opacity[0.5],PointSize[0.02],Point[p,VertexColors->RandomChoice[{{0,0,0},{1,0,0},{0,1,0},{0,0,1},{1,1,0},{0,1,1},{1,0,1},{1,1,1}},100]],Line[p]}]

Manipulate[sp=Developer`ToPackedArray[Normalize/@RandomReal[{-1,1},{n,3}]];
Graphics3D[{f[sp,VertexNormals->sp]}],{{n,2000,"Number of Points"},1000,20000,1000},{{f,Line,"Primititve"},{Point,Line}}]

obj=RevolutionPlot3D[{8+Cos[t],2Sin[t]},{t,0,2Pi},Mesh->None,PlotStyle->FaceForm[None],Axes->False];
m=Grid[Table[Show[obj,Lighting->({"Spot",ColorData["SouthwestColors"][RandomReal[]],Scaled[#],{Pi/4,100}}&)/@RandomReal[{-4,4},{5,3}]],{3},{3}]];
m/.GraphicsComplex[pts_,prims_,rest___]:>GraphicsComplex[pts,Append[prims,{PointSize[0.03],Point[Range[Length[pts]],VertexNormals->Automatic]}],rest]
m/.GraphicsComplex[pts_,prims_,rest___]:>GraphicsComplex[pts,Append[prims,{Line[Range[Length[pts]],VertexNormals->Automatic]}],rest]

More Features For 7

3D Hit testing

KeyWords: Tooltip  ▪Mouseover ▪  EventHandler  ▪  Point  ▪ Polygon  ▪ Tube  ▪ Line  ▪ Cone  ▪  Cylinder  ▪  Tube  ▪  Sphere  ▪Cuboid  ▪ BezierCurve  ▪ BSplineCurve  ▪  Arrow

{Graphics3D[Mouseover[
Sphere[],{Red,Sphere[]}]],Graphics3D[Mouseover[
Cylinder[],{Red,Cylinder[]}]],Graphics3D[Mouseover[
Cone[],{Red,Cone[]}]],Graphics3D[Mouseover[
Cuboid[],{Red,Cuboid[]}]],Graphics3D[Mouseover[
Polygon[{{0,0,0},{1,1,1},{1,0,0}}],{Red,Polygon[{{0,0,0},{1,1,1},{1,0,0}}]}]],Graphics3D[Mouseover[
{Thickness[.02],Line[{{0,0,0},{1,1,1},{1,0,0}}]},{Red,Thickness[.02],Line[{{0,0,0},{1,1,1},{1,0,0}}]}]],Graphics3D[Mouseover[
{PointSize[.1],Point[{{0,0,0},{1,1,1},{1,0,0}}]},{Red,PointSize[.1],Point[{{0,0,0},{1,1,1},{1,0,0}}]}]],Graphics3D[Mouseover[
{Tube[{{0,0,0},{1,1,1},{1,0,0}},.1]},{Red,Tube[{{0,0,0},{1,1,1},{1,0,0}},.1]}]],Graphics3D[Mouseover[
{Thickness[.02],BezierCurve[{{0,0,0},{1,1,1},{1,0,0}}]},{Red,Thickness[.02],BezierCurve[{{0,0,0},{1,1,1},{1,0,0}}]}]],Graphics3D[Mouseover[
{Tube[BezierCurve[{{0,0,0},{1,1,1},{1,0,0}},0.05]]},{Red,Tube[BezierCurve[{{0,0,0},{1,1,1},{1,0,0}},0.05]]}]],Graphics3D[Mouseover[
{Thickness[.02],Arrowheads[.1],Arrow[{{0,0,0},{1,1,1}}]},{Red,Thickness[.02],Arrowheads[.1],Arrow[{{0,0,0},{1,1,1}}]}]],Graphics3D[Mouseover[
{Arrowheads[.2],Arrow[Tube[{{0,0,0},{1,1,1}},0.02]]},{Red,Arrowheads[.2],Arrow[Tube[{{0,0,0},{1,1,1}},0.02]]}]]}

More Features For 7

Multi-primitive

KeyWords: Point  ▪ Polygon  ▪ Tube  ▪ Line  ▪ Cone  ▪  Cylinder  ▪  Tube  ▪  Sphere  ▪BezierCurve  ▪ BSplineCurve  ▪

Graphics3D[Cone[{{{0,0,-1},{1,0,1}},{{1,0,1},{1,2,3}},{{1,2,3},{0,0,0}}}]]

p = RandomReal[{-1,1},{10000,3}];
q = RandomChoice[{{0,0,0},{1,0,0},{0,1,0},{0,0,1},{1,1,0},{0,1,1},{1,0,1},{1,1,1}},10000];
CreateDocument[Graphics3D[{PointSize[0.02],Point[p,VertexColors->q]}],"ShowFrameRateCounter"->True,CacheGraphics->False];
CreateDocument[Graphics3D[{PointSize[0.02],Table[{RGBColor[q[[a]]],Point[p[[a]]]},{a,1,10000}]}],"ShowFrameRateCounter"->True,CacheGraphics->False];

Tricks to Improve Performance

Use Multi-primitive form

Using separate boxes will taking much more formatting time, and even rendering time

Tricks to Improve Performance

Select suitable tube Caps, Joins, and Tube points

Table[Graphics3D[{CapForm[cap],Tube[{{-1,1,-1},{1,-1/2,1}},0.7]},PlotRange->2,PlotLabel->Row[{cap}],Boxed->False],{cap,{None,"Butt","Round","Square"}}]

Table[Graphics3D[{JoinForm[j],Tube[{{-1,-1,-1},{0,0,1},{1,1,-1}},0.4]},PlotRange->2,PlotLabel->Row[{j}],Boxed->False],{j,{None,"Bevel","Round","Miter"}}]

Manipulate[Graphics3D[{Tube[{{0,0,0},{1,1,1}},r]},Method->{"TubePoints"->Dynamic[p]}],{{p,3},3,100,1},{{r,1},0,1}]

Tricks to Improve Performance

Avoid putting a lot of data in Arrowheads directive within Dynamic

Keep transferring a large mount of data back and force can kill the application.

Tricks to Improve Performance

Place Dynamic appropriately when using GeometricTransformation

Packed array helps to reduce data transfer time.

gr={(*the house*){Darker[Red,0.3],Cuboid[{-10,-10,0},{2,3,12}]},(*roof*){Darker[Brown,0.4],Polygon[{{-10,-10,12},{-4,-3,18},{2,-10,12}}]},{Darker[Brown,0.4],Polygon[{{2,-10,12},{-4,-3,18},{2,3,12}}]},{Darker[Brown,0.4],Polygon[{{2,3,12},{-4,-3,18},{-10,3,12}}]},{Darker[Brown,0.4],Polygon[{{-10,3,12},{-4,-3,18},{-10,-10,12}}]},(*Door*){Yellow,Polygon[{{2.005,-5.25,0},{2.005,-5.25,5},{2.005,-1.75,5},{2.005,-1.75,0}}]},(*Door Knob*){Orange,Sphere[{2.005,-2.25,2.5},0.25]},(*Windows*){Lighter[Blue,0.5],Polygon[{{2.005,-9,6},{2.005,-9,10},{2.005,-5,10},{2.005,-5,6}}]},{Lighter[Blue,0.5],Polygon[{{2.005,-1.75,6},{2.005,-1.75,10},{2.005,2,10},{2.005,2,6}}]},(*Chimney*){Gray,Cuboid[{-2,-9,12.75},{-5,-7,17}]},(*Lines for the Window*){Black,Cuboid[{2.006,-9,7.9},{2.006,-5,8.1}]},{Black,Cuboid[{2.006,-7.1,6},{2.006,-6.9,10}]},{Black,Cuboid[{2.006,0,6},{2.006,0.2,10}]},{Black,Cuboid[{2.006,-1.75,7.9},{2.006,2,8.1}]},(*Lawn*){Darker[Green,0.5],Polygon[{{2,-10,0},{2,3,0},{-10,3,0},{-10,10,0},{2,10,0},{10,10,0},{10,-10,0}}]},(*Pavement*){Darker[Gray,0.5],Polygon[{{2,-5.25,0.005},{2,-1.75,0.005},{10,-1.75,0.005},{10,-5.25,0.005}}]},(*Side Windows*){Lighter[Blue,0.5],Polygon[{{1,3.005,2},{1,3.005,5},{-4,3.005,5},{-4,3.005,2}}]},{Lighter[Blue,0.5],Polygon[{{-5,3.005,7},{-9,3.005,7},{-9,3.005,10},{-5,3.005,10}}]},{Lighter[Blue,0.5],Polygon[{{0,3.005,7},{0,3.005,11},{-2,3.005,11},{-2,3.005,7}}]},{Lighter[Blue,0.5],Polygon[{{-6,3.005,2},{-6,3.005,6},{-8,3.005,6},{-8,3.005,2}}]},{Lighter[Blue,0.5],Polygon[{{1,-10.005,2},{1,-10.005,5},{-4,-10.005,5},{-4,-10.005,2}}]},{Lighter[Blue,0.5],Polygon[{{-5,-10.005,7},{-9,-10.005,7},{-9,-10.005,10},{-5,-10.005,10}}]},{Lighter[Blue,0.5],Polygon[{{0,-10.005,7},{0,-10.005,11},{-2,-10.005,11},{-2,-10.005,7}}]},{Lighter[Blue,0.5],Polygon[{{-6,-10.005,2},{-6,-10.005,6},{-8,-10.005,6},{-8,-10.005,2}}]},(*Back Window*){Lighter[Blue,0.5],Polygon[{{-10.005,1,3},{-10.005,1,9},{-10.005,-8,9},{-10.005,-8,3}}]},(*Lines for the Window*){Black,Cuboid[{-1.4,3.006,2},{-1.6,3.006,5}]},{Black,Cuboid[{1,3.006,3.4},{-4,3.005,3.6}]},{Black,Cuboid[{-6.85,3.006,7},{-7.1,3.006,10}]},{Black,Cuboid[{-5,3.006,8.4},{-9,3.006,8.6}]},{Black,Cuboid[{-1.4,-10.006,2},{-1.6,-10.006,5}]},{Black,Cuboid[{1,-10.006,3.4},{-4,-10.005,3.6}]},{Black,Cuboid[{-6.85,-10.006,7},{-7.1,-10.006,10}]},{Black,Cuboid[{-5,-10.006,8.4},{-9,-10.006,8.6}]}};

transx;
Slider[Dynamic[transx]]
Graphics3D[{{Blue,gr},GeometricTransformation[{Red,gr},TranslationTransform[{Dynamic[transx*10],0,0}]]},Boxed->False,ImageSize->{500,500}]

Slider[Dynamic[transx]]
Graphics3D[{{Blue,gr},Dynamic[GeometricTransformation[{Red,gr},TranslationTransform[{transx*10,0,0}]]]},Boxed->False,ImageSize->{500,500}]

Tricks to Improve Performance

Use packed array, if you pass in a large amount of data

Packed array helps to reduce data transfer time.

p = RandomReal[{-1,1},{300000,3}];
Needs["Developer`"];

ByteCount[FromPackedArray[p]]

ByteCount[ToPackedArray[p]]

CreateDocument[Graphics3D[Line[ToPackedArray[p]]],"ShowFrameRateCounter"->True,CacheGraphics->False];
CreateDocument[Graphics3D[Line[FromPackedArray[p]]],"ShowFrameRateCounter"->True,CacheGraphics->False];

Tricks to Improve Performance

Do not use transparency if you don’t need it

3D transparency is still expensive because of the Multiple Rendering.

CreateDocument[Graphics3D[Table[With[{p={i,j,k}*2},{Opacity[1],Sphere[p]}],{i,5},{j,5},{k,5}]],"ShowFrameRateCounter"->True,CacheGraphics->False];
CreateDocument[Graphics3D[Table[With[{p={i,j,k}*2},{Opacity[.99],Sphere[p]}],{i,5},{j,5},{k,5}]],"ShowFrameRateCounter"->True,CacheGraphics->False];

Set the correct layers for Depth Peeling

The.current default setting is 8 layers,

CreateDocument[Graphics3D[{Opacity[.5],Sphere[]}],"ShowFrameRateCounter"->True,CacheGraphics->False];
CreateDocument[Graphics3D[{Opacity[.5],Sphere[]},Method->{"Layers"->2}],"ShowFrameRateCounter"->True,CacheGraphics->False];

Tricks to Improve Performance

Do not enable Antialiasing if you don’t need it

Antialiasing is expensive, on some computer making full use of antialiasing quality will slow the application by several times.

Beyond 3D Primitives

A lot of functions

Visualization and Graphics

Application

Make your own function to visualize your research and simulation

Particle System Simulation

cf =Compile[{{v,_Real,2},{p,_Real,2},{n,_Real}},{Table[{v[[i,1]], v[[i,2]],If[p[[i,3]]>0 && p[[i,3]]+v[[i,3]]-0.049≤0 && p[[i,2]]+v[[i,2]]*2/3>-2 &&p[[i,2]]+v[[i,2]]<2&&p[[i,1]]+v[[i,1]]>-2&&p[[i,1]]+v[[i,1]]<2,-v[[i,3]]/2,v[[i,3]]-0.098]},{i,n}], Table[{p[[i,1]]+v[[i,1]], p[[i,2]]+v[[i,2]],If[p[[i,3]]>0 && p[[i,3]]+v[[i,3]]-0.049≤0 && p[[i,2]]+v[[i,2]]>-2 &&p[[i,2]]+v[[i,2]]<2&&p[[i,1]]+v[[i,1]]>-2&&p[[i,1]]+v[[i,1]]<2,p[[i,3]]/2,p[[i,3]]+v[[i,3]]-0.049]},{i,n}]}];
ck =Compile[{{v,_Real,2},{p,_Real,2},{n,_Real}},{Table[If[p[[i,3]]<-2,{.2*RandomReal[{-1,1}],.2*RandomReal[{-1,1}],.2*(1+RandomReal[])},{v[[i,1]],v[[i,2]],v[[i,3]]}],{i,n}],Table[If[p[[i,3]]<-2,{0,0,0},{p[[i,1]],p[[i,2]],p[[i,3]]}],{i,n}]}];

Manipulate[DynamicModule [{v =Table[{.2*RandomReal[{-1,1}],.2*RandomReal[{-1,1}],.2*(1+RandomReal[])},{i,n}],p=RandomReal[{0,0},{n,3}]},Graphics3D[{Green,Cuboid[{-2,-2,-.1},{2,2,0}],color,PointSize[size],Arrowheads[size],EdgeForm[None],Switch[s,"Point",Point[Dynamic[If[r,{{v,p}=cf[v,p,n];{v,p}=ck[v,p,n]}];p]],"Line",Line[Dynamic[If[r,{{v,p}=cf[v,p,n];{v,p}=ck[v,p,n]}];Table[{{p[[i,1]],p[[i,2]],p[[i,3]]},{p[[i,1]]+v[[i,1]],p[[i,2]]+v[[i,2]],p[[i,3]]+v[[i,3]]}},{i,n}]]],"Polygon",Polygon[Dynamic[If[r,{{v,p}=cf[v,p,n];{v,p}=ck[v,p,n]}];Table[{{p[[i,1]]+v[[i,2]]/2,p[[i,2]]-v[[i,1]]/2,p[[i,3]]},{p[[i,1]]-v[[i,2]]/2,p[[i,2]]+v[[i,1]]/2,p[[i,3]]},{p[[i,1]]+v[[i,1]],p[[i,2]]+v[[i,2]],p[[i,3]]+v[[i,3]]}},{i,n}]]]]},PlotRange->{{-3,3},{-3,3},{-2,3}}]],{{n,1},1,500,1},{{color,Red,"Color"},{Black->"Black",Red->"Red",Green->"Green",Blue->"Blue",Yellow->"Yellow"}},{{size,.02,"PointSize"},0.001,0.05,.001},{{s,"Point","Primitive"},{"Point","Line","Polygon"}},{{r,False,"evolve"},{False,True}},SaveDefinitions->True]

Application

Build your own 3D Object Editor

lastsel;
lasttrans;
lastradius;
lastcolor;
radii = {1,1};
t={{0,0,0},{0,0,0}};
p0={{1,1,0},{5,0,0}};
sel=1;
obj=2;
col={Red,Blue};
updatePoint[index_,trans_, color_,radius_]:=(If[index===sel&&(lastsel=!=sel||lasttrans=!=trans||lastcolor=!=color||lastradius=!=radius),lasttrans=trans;lastsel=sel;lastcolor=color; col[[index]]=color;lastradius=radius;radii[[index]]=radius; t[[index]]=trans];position[index])
position[index_]:=p0[[index]]+t[[index]];

Manipulate[Graphics3D[{If[obj>0,{Table[With[{j=i},EventHandler[{col[[j]],Sphere[With[{start=updatePoint[j,{p[[1]],p[[2]],0},c,r]},Dynamic@start],radii[[j]]]},{"MouseClicked":>(sel=j;p=Take[t[[sel]],2];r=Take[radii[[sel]]];c=Take[col[[sel]]])}]],{i,obj}],Green,Cuboid[{-10,-10,-2.4},{10,10,-2}],Arrowheads[0.04],{Red,Arrow[Tube[{position[sel],position[sel]+{5,0,0}}]],Blue ,Arrow[Tube[{position[sel],position[sel]+{0,5,0}}]]}},{Green,Cuboid[{-10,-10,-2.4},{10,10,-2}]}]},PlotRange->10,PlotLabel->"Please click to select a sphere.",Method->{"TubePoints"->{3,2}}],{{p,{0,0},"Position"},{-10,-10},{10,10}},{{r,1,"Radius"},0,3},{{c,Red,"Color"},{Red,Blue,Green,Yellow,White,Black,Gray,Magenta,Brown,Orange,Pink,Purple}},Button["Add a sphere",{t=Append[t,{0,0,0}],p0=Append[p0,{0,0,0}],radii=Append[radii,1],col=Append[col,RandomChoice[{Red,Blue,Green,Yellow,White,Black,Gray,Magenta,Brown,Orange,Pink,Purple}]],obj++,If[obj===1,{ sel = obj,p={0,0},r=1,c=Red}]}],Button["Delete selected sphere",If[sel>0,{t=Delete[t,sel],p0=Delete[p0,sel],radii=Delete[radii,sel],col=Delete[col,sel],obj--,If[sel>obj, sel = obj],If[sel>0,{p=Take[t[[sel]],2],r=Take[radii[[sel]]],c=Take[col[[sel]]]}]}]]]

Questions?