>
All rights reserved. Matt Kawski. November 1999.
>
Warning -- this is pure exploration, likely still
full of bugs. Nonetheless the last few images do
give the idea -- they are great images!!!!!
>
restart;
with(plots):
with(plottools):
Colorwheel idea
>
plot3d([x,y,0],x=-2..2,y=-2..2,
color=COLOR(RGB,
(1-tanh(log(x^2+y^2)))*(1+(x+y)/sqrt(x^2+y^2)),
(1-tanh(log(x^2+y^2)))*(1+(y-x)/sqrt(x^2+y^2)),
(1-tanh(log(x^2+y^2)))*(1-2*y/sqrt(x^2+y^2))
),
orientation=[-90,0],scaling=constrained,
style=patchnogrid,axes=none);
MAPLE's HUE-colors' don't work. So how to map
the complex plane onto the faces of the RGB-color
cube with preferrably only a few if/max, but no
analytic function evaluations?
Preliminary investigations.
>
box:=
spacecurve([[0,0,0],[1,0,0],[1,1,0],[0,1,0],[0,0,0]],color=black),
spacecurve([[0,0,1],[1,0,1],[1,1,1],[0,1,1],[0,0,1]],color=black),
spacecurve([[0,0,0],[0,0,1]],color=black),
spacecurve([[1,0,0],[1,0,1]],color=black),
spacecurve([[1,1,0],[1,1,1]],color=black),
spacecurve([[0,1,0],[0,1,1]],color=black):
>
myaxes:=spacecurve([[0,0,0],[1.3,0,0]],thickness=2,color=black),
spacecurve([[0,0,0],[0,1.3,0]],thickness=2,color=black),
spacecurve([[0,0,0],[0,0,1.3]],thickness=2,color=black):
>
r:=0.04:
corners:=op(map(q->
sphere(q,r,style=patchnogrid,color=COLOR(RGB,op(q))),
[[0,0,0],[1,0,0],[1,1,0],[0,1,0],[0,0,1],[1,0,1],[0,1,1]])),
sphere([1,1,1],r,style=patchnogrid,color=COLOR(RGB,.95,.95,.95)):
>
display([myaxes,box,corners],
scaling=constrained,
orientation=[-58,76],axes=none);
The idea is to use the brightness for the magnitude, and the color=hue for
the argument. The problem is that the planes transveral to [1,1,1] do not
exactly intersecti the cube in the easiest possible fashion.
think of saturation as the distance from diagonal towards faces....
>
s1:=b->polygonplot3d([[3*b,0,0],[0,3*b,0],[0,0,3*b]]):
s2:=b->polygonplot3d([[1,3*b-1,0],[1,0,3*b-1],[3*b-1,0,1],
[0,3*b-1,1],[0,1,3*b-1],[3*b-1,1,0]]):
s3:=b->polygonplot3d([[3*b-2,1,1],[1,3*b-2,1],[1,1,3*b-2]]):
display([seq(display([myaxes,box,corners,s1(b)]),b=[seq(0+0.05*k,k=1..6)]),
seq(display([myaxes,box,corners,s2(b)]),b=[seq(0+0.05*k,k=7..13)]),
seq(display([myaxes,box,corners,s3(b)]),b=[seq(0+0.05*k,k=14..20)])],
insequence=true,scaling=constrained,
orientation=[-24,73],axes=none);
>
pa1:=[[(1-s+3*h*s)*b,(1+2*s-3*h*s)*b,(1-s)*b],
[(1-s)*b,(1-s+3*h*s)*b,(1+2*s-3*h*s)*b],
[(1+2*s-3*h*s)*b,(1-s)*b,(1-s+3*h*s)*b]]:
>
pa3:=[[(1-s)*b+s*(h+(1-h)*(3*b-2)),(1-s)*b+s*((1-h)+h*(3*b-2)),b-s*b+s],
[b-s*b+s,(1-s)*b+s*(h+(1-h)*(3*b-2)),(1-s)*b+s*((1-h)+h*(3*b-2))],
[(1-s)*b+s*((1-h)+h*(3*b-2)),b-s*b+s,(1-s)*b+s*(h+(1-h)*(3*b-2))]]:
>
display( [seq(
display([myaxes,box,corners,
op(map(q->
plot3d(q,s=0..1,h=0..1,color=COLOR(RGB,op(q)),
grid=[3,3],style=patchnogrid),pa1))]),
b=[0.1,0.2,0.3]),
seq(
display([myaxes,box,corners,
op(map(q->
plot3d(q,s=0..1,h=0..1,color=COLOR(RGB,op(q)),
grid=[3,3],style=patchnogrid),pa3))]),
b=[0.7,0.8,0.9])
],insequence=true,
scaling=constrained,
orientation=[-24,73],axes=none);
The colors look good -- but it lokkslike a lot of work.
>
A different idea is not to project onto the cube's faces, but instead onto a (double) cone whose
abse is the regular hexagon in the plane 2(x+y+z)=3.
>
lower:= op(map(q->plot3d(q,m=0.02..0.49,h=0.02..0.98,color=COLOR(RGB,op(q)),
grid=[3,3],style=patchnogrid),
[[2*m,m*h,m*(1-h)],
[m*h,m*(1-h),2*m],
[m*(1-h),2*m,m*h],
[m*(2-h),0,m*(h+1)],
[m*(1+h),m*(2-h),0],
[0,m*(2-h),m*(1+h)]])):
>
upper:=op(map(q->plot3d(q,m=0.51..0.98,h=0.02..0.98,color=COLOR(RGB,op(q)),
grid=[3,3],style=patchnogrid),
[[1,(1-h)*(1-m)+(2*m-1)*1,h*(1-m)+(2*m-1)*1],
[(1-h)*(1-m)+(2*m-1)*1,h*(1-m)+(2*m-1)*1,1],
[h*(1-m)+(2*m-1)*1,1,(1-h)*(1-m)+(2*m-1)*1],
[m+h-m*h,2*m-1,1-h+h*m],
[2*m-1,1-h+h*m,m+h-m*h],
[1-h+h*m,m+h-m*h,2*m-1]])):
>
display([myaxes,box,corners,lower],
scaling=constrained,
orientation=[-24,73],axes=none);
>
display([myaxes,box,corners,upper],
scaling=constrained,
orientation=[-24,73],axes=none);
>
display([myaxes,box,corners,lower,upper],
scaling=constrained,
orientation=[-24,73],axes=none);
The colors look pretty good -- even without full saturation.
>
col:=proc(x,y)
local b, h, xi, eta;
r:=sqrt(x^2+y^2)+0.00001;
b:=evalf(1-tanh(r/3));
if ( b < 1)
then
COLOR(RGB,b,b,b);
else
COLOR(RGB,1,1,1);
fi;
end:
>
plot3d([u,v,0],u=-2..2,v=-2..2,
color='col(u,v)',
orientation=[-90,0],scaling=constrained,
style=patchnogrid);
Warning, `r` is implicitly declared local
Error, (in col) cannot evaluate boolean
>
p:=proc(x):
if x<0 then 1 else 0 fi;
end:
The same old trouble -- the Boolean expressions inside the colorfunctions
are evaluated prematurely -- before the variables have been assigned values
by the plot function.
This can be handles, but is a pain in the neck -- maybe later.
> plot('p(x)',x=-3..3);
>
Another idea: Use a smooth approximation -- the cost
is slower evaluation of the color values, the advantage
is no trouble with prematurely evaluated Boolean expressions
>
f:=x->1-abs(2*x-1):
g:=x->1-sqrt((2*x-1)^2+.01);
plot([f,g],0..1);
>
plot3d([g(b)*cos(2*Pi*h)/2,g(b)*sin(2*Pi*h)/2,b],b=0..1,h=0..1,
scaling=constrained,orientation=[77,85]);
>
Now fit this shape into the color cube:
>
R:=(x,y,z)->[z+(x+y)/3,
z+(y-x)/3,
z-y/2];
>
display([myaxes,box,corners,
plot3d(R( g(b)*cos(2*Pi*h),
g(b)*sin(2*Pi*h),
b),
b=0..1,h=0..1,
color=COLOR(RGB,op(R( g(b)*cos(2*Pi*h),
g(b)*sin(2*Pi*h),
b))))],
scaling=constrained,
orientation=[-58,76],axes=none);
The white does not yet show up clearly -- need something better than log(x^2)....
but at least this is a start.
>
plot3d([x,y,0],x=-2..2,y=-2..2,
color=COLOR(RGB,op(R(
g(1-tanh(log(x^2+y^2)))*x/sqrt(x^2+y^2),
g(1-tanh(log(x^2+y^2)))*y/sqrt(x^2+y^2),
(1-tanh(log(x^2+y^2)))))),
orientation=[-90,0],scaling=constrained,
style=patchnogrid,axes=none);
>
cplot:=(u,v,xrange,yrange)->
plot3d([x,y,sqrt(u^2+v^2)],xrange,yrange,
color=COLOR(RGB,op(R(
g(1-tanh(log(u^2+v^2)))*(u/sqrt(u^2+v^2)),
g(1-tanh(log(u^2+v^2)))*(v/sqrt(u^2+v^2)),
(1-tanh(log(u^2+v^2)))))),
orientation=[-90,0],scaling=constrained,
style=patchnogrid,axes=none):
>
c0plot:=(u,v,xrange,yrange)->
plot3d([x,y,0],xrange,yrange,
color=COLOR(RGB,op(R(
g(1-tanh(log(u^2+v^2)))*(u/sqrt(u^2+v^2)),
g(1-tanh(log(u^2+v^2)))*(v/sqrt(u^2+v^2)),
(1-tanh(log(u^2+v^2)))))),
orientation=[-90,0],scaling=constrained,
style=patchnogrid,axes=none):
Note the color reversal in the conjugate
>
cplot(x,y,x=-1..1,y=-1..1);
cplot(x,-y,x=-1..1,y=-1..1);
>
display(cplot(x^2+y^2,2*x*y,x=-1..1,y=-1..1),
title=`explain why this does not look analytic`);
> cplot(x^2-y^2,2*x*y,x=-1..1,y=-1..1);
> c0plot(x/(x^2+y^2),-y/(x^2+y^2),x=-3..3,y=-3..3);
>
assume(x,real);
assume(y,real);
w:=evalc(1/(x+I*y-1)+1/(x+I*y+1));
Re(w),Im(w);
> c0plot(Re(w),Im(w),x=-3..3,y=-3..3);
This just does not look right -- where is the bug?
Want a darkness - scaling parameter....
> display(c0plot(Re(w)/2,Im(w)/2,x=-3..3,y=-3..3),axes=frame);
> plot3d(Re(w),x=-3..3,y=-3..3,axes=frame);
> c0plot(Re(w)/2,Im(w)/2,x=-3/2..3/2,y=-3/2..3/2);
>
w:=N->evalc(subs(z=x+I*y,convert(taylor(1/(1-z),z=0,N),polynom))):
w(2);
w(3);
w(4);
w(5);
>
for k from 2 to 4 do
display(c0plot(Re(w(k)),Im(w(k)),x=-2..2,y=-2..2),
labels=[`x`,`y`,` `],axes=frame);
od;
>
The first attempt -- using color to visualize convergence
of Taylor and Laurent expansions.
>
>
w:=N->evalc(subs(z=x+I*y,1/(1-z)-convert(taylor(1/(1-z),z=0,N),polynom))):
w(2);
w(3);
w(4);
w(5);
>
for k from 2 to 4 do
display(c0plot(Re(w(k)),Im(w(k)),x=-2..2,y=-2..2),
labels=[`x`,`y`,` `],axes=frame);
od;
>
w:=N->evalc(subs(z=x+I*y,1/(1-z)-convert(taylor(1/(1-z),z=infinity,N),polynom))):
w(2);
w(3);
w(4);
w(5);
>
display(c0plot(Re(w(2)),Im(w(2)),x=-2..2,y=-2..2),
labels=[`x`,`y`,` `],axes=frame);
>
display(c0plot(Re(w(3)),Im(w(3)),x=-2..2,y=-2..2),
labels=[`x`,`y`,` `],axes=frame);
>
display(c0plot(Re(w(4)),Im(w(4)),x=-2..2,y=-2..2),
labels=[`x`,`y`,` `],axes=frame);
>
display(c0plot(Re(w(5)),Im(w(5)),x=-2..2,y=-2..2),
labels=[`x`,`y`,` `],axes=frame);
>
w:=N->evalc(subs(z=x+I*y,
1/(2-z)-convert(taylor(1/(2-z),z=infinity,N),polynom)
+1/(1+z)-convert(taylor(1/(1+z),z=infinity,N),polynom))):
w(3);
>
display(c0plot(Re(w(4)),Im(w(4)),x=-3..3,y=-3..3),
labels=[`x`,`y`,` `],axes=frame);
>
w:=N->evalc(subs(z=x+I*y,
1/(2-z)-convert(taylor(1/(2-z),z=0,N),polynom)
+1/(1+z)-convert(taylor(1/(1+z),z=infinity,N),polynom))):
>
w(3);
display(c0plot(Re(w(3))/2,Im(w(3))/2,x=-3..3,y=-3..3),
labels=[`x`,`y`,` `],axes=frame);
>
display(c0plot(Re(w(4)),Im(w(4)),x=-3..3,y=-3..3),
labels=[`x`,`y`,` `],axes=frame);
>
w:=N->evalc(subs(z=x+I*y,
1/(2-z)-convert(taylor(1/(2-z),z=0,N),polynom)
+1/(1+z)-convert(taylor(1/(1+z),z=0,N),polynom))):
>
w(3);
display(c0plot(Re(w(4)),Im(w(4)),x=-3..3,y=-3..3),
labels=[`x`,`y`,` `],axes=frame);
>
>
>
>