This repository was archived by the owner on May 7, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathpolar-coordinate-system-pi.ts
116 lines (98 loc) · 3.81 KB
/
polar-coordinate-system-pi.ts
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
/**
* @ignore true
*/
// import Interactive from 'https://unpkg.com/@interactive-svg/library/dist/Interactive.js';
import {Interactive, getScriptName, download, Line, Circle} from '../../index.js';
// Initialize the interactive
let margin = 32;
let interactive = new Interactive(getScriptName());
interactive.border = false;
interactive.originX = interactive.width/2;
interactive.originY = interactive.width/2;
interactive.height = interactive.width;
interactive.style.overflow = 'visible';
// Create three control points
let point = interactive.control(0,0);
let radius = 50;
let n = 5;
let border = interactive.circle(0,0,n*radius);
// Create a path
let path = interactive.path('');
path.addDependency(point);
path.root.style.fill = 'rgb(236,236,236)';
path.update = function() {
let flag = (point.y > 0) ? 1 : 0;
let angle = getAngle();
let r = 50;
path.d = `M 0 0
L ${r} 0
A ${r} ${r} 0 ${flag} 0 ${r*Math.cos(angle)} ${-r*Math.sin(angle)}
z`;
};
path.update();
let xAxis = interactive.line( -interactive.width/2 + margin, 0, interactive.width/2 - margin, 0);
let yAxis = interactive.line( 0, -interactive.height/2 + margin, 0, interactive.height/2 - margin);
// let rectangle = interactive.rectangle(xAxis.x1, yAxis.y1, xAxis.x2 - xAxis.x1, yAxis.y2 - yAxis.y1);
point.constrainWithin( border);
let marker = interactive.marker(10, 5, 10, 10);
marker.path('M 0 0 L 10 5 L 0 10 z').style.fill = '#404040';
marker.setAttribute('orient', 'auto-start-reverse');
xAxis.setAttribute('marker-end', `url(#${marker.id})`);
xAxis.setAttribute('marker-start', `url(#${marker.id})`);
yAxis.setAttribute('marker-end', `url(#${marker.id})`);
yAxis.setAttribute('marker-start', `url(#${marker.id})`);
let right = interactive.text( xAxis.x2 + 16, xAxis.y2, '0, 2π');
right.setAttribute('dominant-baseline', 'middle');
let top = interactive.text( yAxis.x1, yAxis.y1 - 16, 'π/2');
top.setAttribute('text-anchor','middle');
let left = interactive.text( xAxis.x1 - 20, xAxis.y2, 'π');
left.setAttribute('dominant-baseline', 'middle');
let bottom = interactive.text( yAxis.x1, yAxis.y2 + 32, '3π/2');
bottom.setAttribute('text-anchor','middle');
let group = interactive.group();
group.style.strokeOpacity = '.2';
group.root.setAttribute('vector-effect','non-scaling-stroke');
let r = 50;
for( let i = 0; i <= n; i++) {
let angle = i*2*Math.PI/12;
let x = border.r*Math.cos(angle);
let y = border.r*Math.sin(angle);
let circle = group.circle(0,0, i*r);
group.line(-x, -y, x, y);
if( i > 0 && i < n ) {
let tempAngle = 0*Math.PI/n;
group.text( circle.r*Math.cos(tempAngle)+ 4, -circle.r*Math.sin(tempAngle) + 20, i.toString());
}
}
let pointRadius = 4*radius;
let pointAngle = 2*2*Math.PI/12;
point.translate( pointRadius*Math.cos(pointAngle), -pointRadius*Math.sin(pointAngle));
let radiusLine = interactive.line(0, 0, 0, 0);
radiusLine.style.stroke = 'cornflowerblue';
radiusLine.addDependency( point );
radiusLine.update = function(){
this.x2 = point.x;
this.y2 = point.y;
};
radiusLine.update();
interactive.circle(0,0,3).style.fill = '#404040';
let text = interactive.text(150, 150, "myText");
text.addDependency(point);
text.update = function() {
this.x = point.x + 15;
this.y = point.y - 15;
this.contents = `(${Math.hypot(point.y/50, point.x/50).toFixed(2)}, ${getAngle().toFixed(2)})`;
};
text.update();
// Gets the normalized angle between zero and tau. TODO: Maybe transform the
// coordinate system so that the positive y-direction is up instead of down.
// UPDATE: transform = 'scale(1,-1)' applied to the main svg didn't quite work
// as expected: the text element was upside down, but maybe that could be
// reversed? bleh.
function getAngle() : number {
if( point.y <= 0 ) {
return Math.abs(Math.atan2( point.y, point.x));
} else {
return Math.PI*2 - Math.atan2( point.y, point.x);
}
}