-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFourFunctionSurface.pde
More file actions
125 lines (118 loc) · 4 KB
/
Copy pathFourFunctionSurface.pde
File metadata and controls
125 lines (118 loc) · 4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
class FourFunctionSurface{
//A 2-manifold embedded in C^2 (R^4) where [x,y]start as [Re(z),Im(z)] and [z,w] start as [Re(f(z)),Im(f(z))]
int xDetail,yDetail;
FourShape shape;
FourVector origin;
FourMatrix planeRotation;
FourMatrix camRotation;
Complex[] z,w;
FourFunctionSurface(FourVector _origin,double xRadius, int _xDetail,double yRadius, int _yDetail){
xDetail = _xDetail; yDetail = _yDetail; origin = _origin;
generateC1(xRadius,yRadius);
resetOrientation();
generateSheet();
}
FourFunctionSurface(FourVector _origin,double[] xBounds, int _xDetail,double[] yBounds, int _yDetail){
xDetail = _xDetail; yDetail = _yDetail; origin = _origin;
generateC1(xBounds,yBounds);
resetOrientation();
generateSheet();
}
void applyFunction(ComplexFunction f){
for (int i=0; i<z.length; i++){
w[i] = f.f(z[i]);
}
}
void iterateFunction(ComplexBinaryFunction f){
for (int i=0; i<z.length; i++){
w[i] = f.f(w[i],z[i]);
}
}
void resetOrientation(){
planeRotation = scalar(1);
camRotation = scalar(1);
generateSheet();
}
void applyMatrix(FourMatrix M,boolean global){
if(global){
camRotation = camRotation.multiply(M);
} else {
planeRotation = planeRotation.multiply(M);
}
shape.applyMatrix(M,global);
}
void generateC1(double xRadius,double yRadius){
double dx = (2*xRadius) / (xDetail-1);
double dy = (2*xRadius) / (yDetail-1);
z = new Complex[xDetail * yDetail];
w = new Complex[xDetail * yDetail];
for (int j=0; j<yDetail; j++){
for (int i=0; i<xDetail; i++){
int ind = i + j*xDetail;
double x = i*dx - xRadius;
double y = j*dy - yRadius;
z[ind] = new Complex(x,y);
w[ind] = new Complex(x,y);
}
}
}
void generateC1(double[] xBounds,double[] yBounds){
if(xBounds.length != 2 || yBounds.length != 2){throw new IllegalArgumentException("xBounds and yBounds must be length 2, 1 lower bound, 1 upper bound");}
double x1 = Math.min(xBounds[0], xBounds[1]);
double x2 = Math.max(xBounds[0], xBounds[1]);
double y1 = Math.min(yBounds[0], yBounds[1]);
double y2 = Math.max(yBounds[0], yBounds[1]);
double dx = (x2-x1) / (xDetail-1);
double dy = (y2-y1) / (yDetail-1);
z = new Complex[xDetail * yDetail];
w = new Complex[xDetail * yDetail];
for (int j=0; j<yDetail; j++){
for (int i=0; i<xDetail; i++){
int ind = i + j*xDetail;
double x = i*dx + x1;
double y = j*dy + y1;
z[ind] = new Complex(x,y);
w[ind] = new Complex(x,y);
}
}
}
void generateSheet(){generateSheet(false);}
void generateSheet(boolean outputColor){
FourVector[] points = new FourVector[xDetail*yDetail];
ArrayList<FourLine> edges = new ArrayList<FourLine>();
FourFace[] faces = new FourFace[0];
for (int j=0; j<yDetail; j++){
for (int i=0; i<xDetail; i++){
int ind = i + j*xDetail;
points[ind] = fourDComplex(z[ind],w[ind]).add(origin);
if( i+1 < xDetail){
color col = (outputColor) ? argandColor(w[ind],1) : argandColor(z[ind],1);
edges.add( new FourLine(ind,ind+1,col) );
}
if( j+1 < yDetail ){
color col = (outputColor) ? argandColor(w[ind],1) : argandColor(z[ind],1);
edges.add( new FourLine(ind,ind+xDetail,col) );
}
}
}
shape = new FourShape(origin,points,edges.toArray(new FourLine[0]),faces);
shape.applyMatrix(planeRotation,false);
shape.applyMatrix(camRotation,true);
}
}
color argandColor(Complex z,double maxExpected){
if (z.isNaN()) {
return color(255);
}
final float hue = (float)(z.arg()%TAU + TAU) % TAU;
final double mag = z.mag();
float l;
if (maxExpected == -1){
l = 0.5;
} else if (mag <= maxExpected) {
l = (float)(0.5d*mag/maxExpected);
} else {
l = (float)(0.5d*(2d - (maxExpected/(Math.log(mag - maxExpected + 1) + maxExpected))));
}
return HSL(hue, 1, l);
}