-
Notifications
You must be signed in to change notification settings - Fork 0
/
hyperbolicQuad.js
executable file
·114 lines (92 loc) · 2.92 KB
/
hyperbolicQuad.js
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
"use strict";
// parameters
var quadScale=20;
// rotational symmetry at center
var quadNCenter=4;
// rotational symmetry at left corner
var quadNLeft=3;
// rotational symmetry at right corner
var quadNRight=4;
// cutoff around disc
var quadCutoff=false;
// angles
var quadAlpha=Math.PI/quadNLeft;
var quadBeta=Math.PI/quadNRight;
var quadGamma=Math.PI/quadNCenter;
// separating the two mirrors
var quadTanGamma=Math.tan(0.5*Math.PI/quadNCenter);
// mirror circles
var quadRadius=0.2;
var quadDistance=quadRadius*Math.cos(0.5*quadAlpha)/Math.sin(0.5*quadGamma);
console.log(quadDistance);
var quadWorldRadius=Math.sqrt(quadDistance*quadDistance-quadRadius*quadRadius);
// rescale world radius to be 0.5
quadRadius*=0.5/quadWorldRadius;
quadDistance*=0.5/quadWorldRadius;
// center of second circle
var quadCenterX=quadDistance*Math.cos(quadGamma);
var quadCenterY=quadDistance*Math.sin(quadGamma);
console.log("cc "+quadCenterX+" "+quadCenterY);
// poincare disc
function quad(inputImagePosition,colorPosition,spacePosition,canvasPosition){
var isFinished=false;
var iter=0;
var iterMax=iterMaximum;
inputImagePosition.set(spacePosition);
colorPosition.x=1; // as parity for 2 colors
if ((inputImagePosition.radius2()>0.25)&&quadCutoff){
return false;
}
while (!isFinished){
colorPosition.x*=inputImagePosition.rotationMirrorSymmetry(quadNCenter);
iter++;
if (iter>iterMax){
return false;
}
// two different mirrors
if (inputImagePosition.y>quadTanGamma*inputImagePosition.x){
isFinished=!inputImagePosition.circleInversionInsideOut(quadCenterX,quadCenterY,quadRadius);
}
else {
isFinished=!inputImagePosition.circleInversionInsideOut(quadDistance,0,quadRadius);
}
if (!isFinished) {
colorPosition.x=-colorPosition.x;
}
isFinished=true;
}
basicRosette(inputImagePosition,nSymmCenter);
inputImagePosition.scale(quadScale);
return true;
}
function quad2(inputImagePosition,colorPosition,spacePosition,canvasPosition){
var isFinished=false;
var iter=0;
var iterMax=iterMaximum;
inputImagePosition.set(spacePosition);
colorPosition.x=1; // as parity for 2 colors
if ((inputImagePosition.radius2()>0.25)&&quadCutoff){
return false;
}
while (!isFinished){
colorPosition.x*=inputImagePosition.rotationMirrorSymmetry(quadNCenter);
iter++;
if (iter>iterMax){
return false;
}
// two different mirrors, is finished=true means there is no inversion
isFinished=!inputImagePosition.circleInversionInsideOut(quadCenterX,quadCenterY,quadRadius);
if (isFinished) { // first circle did not invert, try next
// isFinished=!inputImagePosition.circleInversionInsideOut(quadDistance,0,quadRadius);
}
if (!isFinished) {
colorPosition.x=-colorPosition.x;
}
//isFinished=true;
}
basicRosette(inputImagePosition,nSymmCenter);
inputImagePosition.scale(quadScale);
return true;
}
// improve
var quadRadiusImproved=1;