-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathVector.js
160 lines (124 loc) · 4.5 KB
/
Vector.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
//-----Clairvoyant.js Vector Class------------------------------------------------------
function Vector(elements) {
'use strict';
if (elements && !(elements instanceof Array)) {
throw ('ERROR: Must pass either an array of values OR nothing to Vector constructor.');
}
if (elements) {
this.elements = elements;
this.dimension = elements.length;
} else {
this.elements = [];
this.elements[0] = 0;
this.dimension = 1;
}
// Pass an Array or a single number as <value> to the Vector; single numbers get
// assigned at <position> in the vector.
this.setVal = function (value, position) {
if (!(value instanceof Array) && (typeof position === 'undefined')) {
throw ('ERROR: Must pass either an array of values OR a single number and position.');
}
if (typeof position !== 'undefined') {
this.elements[position] = value;
if (this.dimension < (position + 1)) {
this.dimension = position + 1;
return;
}
} else {
this.elements = value;
this.dimension = value.length;
return;
}
};
// Take the dot product of this Vector with Vector <vector>. Optional Matrix <metric>
// Will be used as a metric (default rectangular Cartesian)
this.dot = function (vector, metric) {
var dimension, sum, left;
if (!(vector instanceof Vector)) {
throw ('ERROR: Not a vector. Must take dot product with another Vector.');
}
if (this.dimension !== vector.dimension) {
throw ('ERROR: Vectors must be the same length to take dot product.');
}
sum = 0;
if (metric) {
// if (!(metric instanceof Matrix)) {
// throw('ERROR: Not a matrix. Second argument, when provided, must always be a matrix.')
// return;
// }
if ((this.dimension !== metric.rows) || (vector.dimension !== metric.cols)) {
throw ('ERROR: Incorrect metric dimension.');
}
left = metric.mtxMulti(this, 'left');
for (dimension = 0; dimension < left.dimension; dimension++) {
sum += left.elements[dimension] * vector.elements[dimension];
}
} else {
for (dimension = 0; dimension < this.dimension; dimension++) {
sum += this.elements[dimension] * vector.elements[dimension];
}
}
return sum;
};
//Returns the length of this Vector. Matrix <metric> optional, default rectangular Cartesian.
this.getLength = function (metric) {
var length;
length = 0;
if (metric) {
length = Math.pow((metric.mtxMulti(this, 'left')).dot(this), 0.5);
} else {
length = Math.pow(this.dot(this), 0.5);
}
return length;
};
// Return this Vector scaled by <scale>
this.scale = function (sc) {
var i, scale, scaledVec;
if (typeof sc !== 'undefined') {
scale = sc;
} else {
scale = 1 / this.getLength();
}
scaledVec = new Vector();
for (i = 0; i < this.dimension; i++) {
scaledVec.setVal(this.elements[i] * scale, i);
}
return scaledVec;
};
// Log this Vector to the window:
this.dump = function () {
var i;
document.write('(');
for (i = 0; i < this.dimension; i++) {
if (i !== this.dimension - 1) {
document.write(this.elements[i] + ', ');
} else {
document.write(this.elements[i] + ')');
}
}
};
//return the Vector projection of this Vector along Vector <vec>:
this.project = function (vec) {
var component, lengthSquared, norm;
component = this.dot(vec);
lengthSquared = vec.dot(vec);
norm = component / lengthSquared;
return vec.scale(norm);
};
//return the sum of this Vector with Vector <vec>
this.add = function (vec) {
var i, sum;
try {
if (this.dimension !== vec.dimension) {
throw ('Vectors must be the same length to add them. Aborting...');
}
} catch (err) {
return;
}
sum = new Vector();
for (i = 0; i < this.dimension; i++) {
sum.setVal(this.elements[i] + vec.elements[i], i);
}
return sum;
};
}