-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathArbitrary Cluster Classification.js
110 lines (103 loc) · 2.42 KB
/
Arbitrary Cluster Classification.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
var w = 500;
var n = 1000;
var pts = [];
var k = 7;
var cent = [];
function dot (x,y){
this.x=x;
this.y=y;
this.h=255;
this.s=0;
this.b=255;
this.centIndex=null
this.drawPoint = function(){
stroke(this.h,this.s,this.b);
point(this.x,this.y);
}
this.drawCentroid = function(){
stroke(this.h,this.s,this.b);
ellipse(this.x,this.y,5);
}
this.closestCentroid = function(centroids){
var s = Infinity;
for (var i=0; i<centroids.length; i++){
if (s>d(this,centroids[i])){
s=d(this,centroids[i]);
this.centIndex=i;
this.h = centroids[i].h;
this.s = centroids[i].s;
this.b = centroids[i].b;
}
}
}
this.recenter = function(points){
var _x=0,_y=0,num=0;
for (var i=0; i<points.length; i++){
if (points[i].centIndex==this.centIndex){
_x += points[i].x;
_y += points[i].y;
num++;
}
}
this.x = _x/num;
this.y = _y/num;
}
this.perturbCentroid = function(e){
this.x += 2*e*Math.random()-e;
this.y += 2*e*Math.random()-e;
}
}
for (var i=0; i<n; i++){
var x = Math.floor(w*Math.random()/k);
var y = Math.floor(w*Math.random()/k);
var d = w*Math.floor(k*Math.random())/k;
pts.push(new dot(x+d,y+d));
}
for (var i=0; i<k; i++){
var x = Math.floor(w*Math.random());
var y = Math.floor(w*Math.random());
cent.push(new dot(x,y));
cent[i].centIndex=i;
cent[i].h=255*i/k;
cent[i].s=255;
cent[i].b=255;
}
function setup() {
colorMode(HSB);
createCanvas(w, w);
noFill();
strokeWeight(3);
frameRate(50);
strength = createSlider(0, 100, 20);
strength.position(10, w+10);
createP('Slider adjusts perturbation strength').position(10, w+20);
}
function draw() {
background(0);
for (var i=0; i<n; i++){
pts[i].drawPoint();
if (frameCount>20){
if (frameCount%2==1){
pts[i].closestCentroid(cent);
}
}
}
for (var i=0; i<k; i++){
cent[i].drawCentroid();
if (frameCount>20){
if (frameCount%2==1){
cent[i].recenter(pts);
if(isNaN(cent[i].x) || cent[i].x<0 || cent[i].x>w){
cent[i].x = w/2;
}
if(isNaN(cent[i].y) || cent[i].y<0 || cent[i].y>w){
cent[i].y = w/2;
}
}
if (frameCount%50==0 && frameCount<1000){
cent[i].perturbCentroid(strength.value());
}
}
}
}
d = (dot1,dot2) => ((dot1.x-dot2.x)*(dot1.x-dot2.x) + (dot1.y-dot2.y)*(dot1.y-dot2.y));