KermMartian wrote:
I hadn't really considered the possibility of supporting parametrized functions, because it would be fairly challenging, at least for Graph3D v1.0. For a future version, I think it would be a good feature to add, especially if one could use it to graph snowmen!
I have some really sweet (procedural/mathematical surface) visualizations in Maple that would be mind-blowing on a hand-held :D Even if I had to calculate the Frenet-Serret frame equations for my spacecurves by hand or not have reusable user-defined convenience functions, being able to use parameterized and/or implicit plots would be amazing. From a computational perspective, I don't think you're missing anything I used in the Maple spreadsheet I used to make the snowman (except for the Frenet-Serret calculations at the beginning). I've transcribed it here, sans the coloring/lighting/window options. Take a look and tell me if you think I'm wrong (as far as capabilities are concerned), but I could see this as a worthy end-goal for your program.
Quote:
> hatpath := t -> <2*t, 0, -(t-1)^2+1>:
> spacecurve(hatpath(t), t = -1 .. 4):
> TNB := TNBFrame(hatpath(t)):
> T := u -> subs(t = u, TNB[1]): N := u -> subs(t = u, TNB[2]): B := u -> subs(t = u, TNB[3]):
Because poofy hats are styling
> pompombumps := (θ, φ) -> 1+(3/32)*sin(16*θ)*sin(16*φ):
> hatfabric := (s,t) -> 4*cos(s)*N(t)+2*sin(s)*B(t):
Christmas-ish red and green lighting from light2
> mainhatplot := plot3d(hatpath(t)+hatfabric(s, t)*exp(.4*(-1-t)), t = -1 .. 4, s = 0 .. 2*π):
We'll re-use this bit a lot. save it as a convenience function
> ball := (ρ, θ, φ) -> <ρ*sin(φ)*cos(θ), ρ*sin(φ)*sin(θ), ρ*cos(φ)>:
> poofplot := plot3d(hatpath(4)+ball(pompombumps(θ, φ), θ, φ), θ = 0 .. 2*π, φ = 0 .. π):
> poofband := (q, r, s, t, u) -> hatfabric(s, t)+pompombumps(s, u)*(q*cos(u)*cos(s)*N(t)+q*cos(u)*sin(s)*B(t)+r*sin(u)*T(t)):
> bandplot := plot3d(hatpath(-1)+poofband(.5, 1, s, -1, u), s = 0 .. 2*π, u = 0 .. 2*π):
Making some snowballs
> snowman := seq(plot3d(ball(4+2*n, θ, φ)-<4, 0, 2+sum(2*((i+.5)*2), i = 1 .. n)>, θ = 0 .. 2*π, φ = 0 .. π), n = 1 .. 3):
Makes a segmented carrot by scaling the top end of the original segment down towards the tip.
> carrotsegment := (o, r, l, t, s) -> {<-7-o, 0, -7>+<r*t, sqrt(r^2-r^2*t^2)*cos(s), sqrt(r^2-r^2*t^2)*sin(s)>, <-7-o, 0, -7>+<-l*t, (r-r*t)*cos(s), (r-r*t)*sin(s)>}:
> carrot := seq(plot3d(carrotsegment(i, e^(-0.5e-1*i), 7-i, t, s), s = 0 .. 2*π, t = 0 .. 1), i = 0 .. 4);
Another convenience function. Eyes, mouth, buttons
> coal := (θ, φ) -> ball(.75, θ, φ):
> eyes := seq(plot3d(coal(θ, φ)+<-7, -3+6*n, -4.5>, θ = 0 .. 2*π, φ = 0 .. π), n = 0 .. 1):
Magic constants based on the snowball formulation above. This uses a spherical coordinate transform, with the ordered triplet rotated one position to the right so that "vertical" is along the x axis. This allows us to base the mouth curve on a single variable, rather than 2
> mouthsphere := (n, θ, φ) -> <6*cos((7/8)*π)-4, 6*sin((7/8)*π)*cos((9/8)*π+(3/16)*n*π), 6*sin((7/8)*π)*sin((9/8)*π+(3/16)*n*π)-8>+coal(θ, φ):
> mouthplot := seq(plot3d(mouthsphere(n, θ, φ), θ = 0 .. 2*π, φ = 0 .. π), n = 0 .. 4):
See above, only we can get away with just using normal spherical coordinates here, since the buttons only rotate along φ.
> button := (n, θ, φ) -> ball(8, π, (3/8)*π+(1/8)*n*π)-<4, 0, 18>+coal(θ, φ):
> buttons := seq(plot3d(button(n, θ, φ), θ = 0 .. 2*π, φ = 0 .. π), n = 0 .. 2):
> armpath := t -> <-3, t, abs(.25*t)-18>:
Taper the arms so they don't appear open at the end (even though they really are)
> armplot := plot3d(armpath(t)+<e^(-.1*abs(t))*cos(s), 0, e^(-.1*abs(t))*sin(s)>, s = 0 .. 2*π, t = -15 .. 15):
> display({armplot, buttons, carrot, eyes, snowman, bandplot, mainhatplot, mouthplot, poofplot});
Similarly, for this shell: http://img821.imageshack.us/img821/4992/shellrender.png