BeginPackage["Circle3D`","Normalize`"] Circle3D::usage = "\n Circle3D[center,radius,normal] returns a circle with specified\n center and radius, on a plane orthogonal to normal.\n Circle3D[center,{semiaxis1,semiaxis2},{t1,t2}] returns an arc of\n the ellipse parametrized by center+semiaxis1 Cos[t]+semiaxis2 Sin[t],\n for t going from t1 to t2. Options are passed to ParametricPlot3D." Circle3D::badnormal = "Normal vector `` should not have length 0" Hyperbola3D::usage = "\n Hyperbola3D[center,{semiaxis1,semiaxis2},{t1,t2}] returns an arc of\n the hyperbola parametrized by center+semiaxis1 Cosh[t]+semiaxis2 Sinh[t],\n for t going from t1 to t2. Options are passed to ParametricPlot3D." Begin["`private`"] Unprotect[Cross] Cross[x_,y_] := RotateLeft[RotateLeft[y] x - RotateLeft[x] y] Circle3D[center_,radius_,normal_?VectorQ,options___] := If[N[normal.normal]==0,Message[Circle3D::badnormal,normal];Null, Block[ {semiaxis1,semiaxis2,l}, semiaxis1=Normalize[ Cross[normal,If[N[normal[[1]]]==N[normal[[2]]]==0,{0,1,0},{0,0,1}]]]; semiaxis2=Normalize[Cross[semiaxis1,normal]]; Circle3D[center,radius{semiaxis1,semiaxis2},{0,2Pi},options]]] Circle3D[center_,{sa1_,sa2_},{t1_,t2_},options___] := fixpp[ParametricPlot3D[center+sa1 Cos[t]+sa2 Sin[t],{t,t1,t2},options, DisplayFunction->Identity, Compiled->False][[1]]] Circle3D[center_,{sa1_,sa2_},options___] := Circle3D[center,{sa1,sa2},{0,2Pi},options] Hyperbola3D[center_,{sa1_,sa2_},{t1_,t2_},options___] := fixpp[ParametricPlot3D[center+sa1 Cosh[t]+sa2 Sinh[t],{t,t1,t2},options, DisplayFunction->Identity, Compiled->False][[1]]] fixpp[x_] := Line[Append[#[[1,1]]&/@x,x[[-1,-1,-1]]]] End[] EndPackage[]