-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcurves.js
126 lines (103 loc) · 2.75 KB
/
curves.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
115
116
117
118
119
120
121
122
123
124
125
Curve.types = {
STRAIGHT_LINE : 0,
BEZIER : 1,
B_SPLINE : 2
}
function Curve(){
//a bunch of control points
this.cPoints = [];
this.lPoints = [];
this.curveType = Curve.types.STRAIGHT_LINE; //default to staight line
this.activePointIndex = -1;
}
Curve.prototype.updateActivePoint = function(pos){
for(var i in curve.cPoints){
if(curve.cPoints[i].equal(pos)){
curve.cPoints[i].active = true;
//selected = curve.cPoints[i];
this.activePointIndex = i;
}else{
curve.cPoints[i].active = false;
}
}
return curve.cPoints[this.activePointIndex]; //return the active point as pointer for future updates
}
Curve.prototype.draw = function(ctx, levelOfDetails){
if (this.cPoints.length > 0) {
this.connectTheDots(ctx);
}
}
Curve.prototype.connectTheDots = function(ctx){
for(var i = 0; i<this.cPoints.length-1; i++){
ctx.beginPath();
ctx.moveTo(this.cPoints[i].x, this.cPoints[i].y);
ctx.lineTo(this.cPoints[i+1].x, this.cPoints[i+1].y);
ctx.stroke();
}
for(var i in this.cPoints){
this.cPoints[i].draw(ctx);
}
}
Curve.prototype.drawLine = function(ctx, pt1, pt2){
ctx.beginPath();
ctx.moveTo(pt1.x, pt1.y);
ctx.lineTo(pt2.x, pt2.y);
ctx.stroke();
}
Curve.prototype.drawNormals = function(){
}
//BEZIER
function Bezier(){
Curve.call(this);
this.curveType = Curve.types.BEZIER
}
Bezier.prototype = Object.create(Curve.prototype);
Bezier.prototype.draw = function(ctx, levelOfDetail){
//var levelOfDetail = 10;
this.connectTheDots(ctx);
if(this.cPoints.length > 1)
{
this.lPoints=[];
//this.normals.clear();
for(var j = 0; j <= levelOfDetail; j++)
{
t = j/(levelOfDetail+0.0);
console.log(t)
p = this.deCasteljau(t, this.cPoints);
this.lPoints.push(p);
}
for(var i=0; i<this.lPoints.length-1; i++)
{
this.drawLine(ctx, this.lPoints[i], this.lPoints[i+1]);
}
//this.drawNormals();
}
}
Bezier.prototype.deCasteljau = function(u, points){
n = points.length-1;
//initialize an matrix to store the state of computation
var ps = [];
for(var i = 0; i<n+1; i++){
ps[i] = [];
for(var j =0; j<n+1; j++){
ps[i][j] = 0;
}
}
for(var level= n; level>=0; level--)
{
if(level==n)
{
for(var i=0; i<=n; i++){
ps[level][i] = points[i];
}
continue;
}
for(var i =0 ; i <= level; i++)
{
var a = (1-u)*ps[level+1][i].x + u*ps[level+1][i+1].x;
var b = (1-u)*ps[level+1][i].y + u*ps[level+1][i+1].y;
ps[level][i] = new Point(a,b);
}
}
return ps[0][0];
}