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 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
|
/**
Library for vector operations.
@author Marky
@credits Randrian, since many functions have their origin in the rope physics library.
*/
/**
Addition of two vectors of the same dimension.
Note: Cannot be named 'Add' because the scenario
save mechanism will throw a lot of warnings.
@par a The first vector.
@par b The second vector.
@return array The vector (a_i + b_i), i=1,...,n.
*/
public func Sum(array a, array b)
{
AssertVectorOperation(a, b);
var vector = [];
for (var i = 0; i < GetLength(a); i++)
{
vector[i] = a[i] + b[i];
}
return vector;
}
/**
Subtraction of two vectors of the same dimension.
@par a The first vector.
@par b The second vector.
@return array The vector (a_i - b_i), i=1,...,n.
*/
public func Subtract(array a, array b)
{
AssertVectorOperation(a, b);
var vector = [];
for (var i = 0; i < GetLength(a); i++)
{
vector[i] = a[i] - b[i];
}
return vector;
}
/**
Multiplication of a vector and a number.
@par a The vector
@par b The number
@return array The vector (b * a_i), i=1,...,n.
*/
public func Multiply(array a, int b)
{
AssertNotNil(a, "vector 'a'");
var vector = [];
for (var i = 0; i < GetLength(a); i++)
{
vector[i] = b * a[i];
}
return vector;
}
/**
Division of a vector and a number.
@par a The vector
@par b The number
@return array The vector (a_i / b), i=1,...,n.
*/
public func Divide(array a, int b)
{
AssertNotNil(a, "vector 'a'");
var vector = [];
for (var i = 0; i < GetLength(a); i++)
{
vector[i] = a[i] / b;
}
return vector;
}
/**
Dot product of two vectors of the same dimension.
@par a The first vector
@par b The second vector
@return int Sum of a_i * b_i, for i = 1,...,n
*/
public func DotProduct(array a, array b)
{
AssertVectorOperation(a, b);
var sum = 0;
for (var i = 0; i < GetLength(a); i++)
{
sum += a[i] * b[i];
}
return sum;
}
/**
Product of the elements of vectors of the same dimension.
@par a The first vector
@par b The second vector
@return array the vector c_i of c_i = a_i * b_i, for i = 1,...,n
*/
public func Product(array a, array b)
{
AssertVectorOperation(a, b);
var vector = [];
for (var i = 0; i < GetLength(a); i++)
{
vector[i] = a[i] * b[i];
}
return vector;
}
/**
Euclidean length of a vector.
@par a The vector.
@return int Square root of the sum of a_i * a_i, for i=1,...,n.
*/
public func Length(array a)
{
return Sqrt(DotProduct(a, a));
}
/**
The dimension of a vector.
@par a The vector
@return int The number of elements of the vector.
*/
public func Dimension(array a)
{
AssertNotNil(a, "vector 'a'");
return GetLength(a);
}
/**
Angle between two vectors.
@par a A two-dimensional vector.
@par b A two-dimensional vector.
@return int The angle between a and b. If you rotate a by this angle,
then it will point in the same direction as b.
*/
public func AngleBetween(array a, array b, int precision)
{
AssertVectorOperation(a, b);
if (!precision) precision = 1;
var rot_a = GetRotation(a, precision);
var rot_b = GetRotation(b, precision);
return rot_b - rot_a;
}
/**
Angle of a vector.
@par a A two-dimensional vector.
@par precision [opt] Multiplied with the angle, for higher precision. A precision of 10 will produce values from 0 to 3600.
@return int The angle of a, relative to the coordinate system.
*/
public func GetRotation(array a, int precision)
{
AssertDimension(a, 2);
if (!precision) precision = 1;
return Angle(0, 0, a[0], a[1], precision);
}
/**
Normalizes a vector with precision.
@par a The vector.
@par precision Factor for the resultion length.
@return array The normalized vector with length = 1 * precision
*/
public func Normalize(array a, int precision)
{
if (!precision) precision = 1;
return Divide(Multiply(a, precision), Length(a));
}
/**
Rotates a vector by an angle.
@par a The vector.
@par angle The angle that the vector is rotated by, clockwise.
@return array The rotated vector.
*/
public func Rotate(array a, int angle, int precision)
{
AssertDimension(a, 2);
if (!precision) precision = 1;
var length_precision = 1000;
var cos = Cos(angle, length_precision, precision);
var sin = Sin(angle, length_precision, precision);
var rotated_x = cos * a[0] - sin * a[1];
var rotated_y = sin * a[0] + cos * a[1];
return [rotated_x / length_precision, rotated_y / length_precision];
}
/**
Assert that a vector operation can be done with these two vectors.
The vectors have to be of the same dimension and their elements
must have the same names.
@par a The first vector, must not be nil.
@par b The second vector, must not be nil.
*/
public func AssertVectorOperation(array a, array b)
{
AssertNotNil(a, "vector 'a'");
AssertNotNil(b, "vector 'b'");
var length_a = GetLength(a);
var length_b = GetLength(b);
if (length_a != length_b)
{
FatalError(Format("This method only works with vectors of the same length. Vector 'a' has %d elements, vector 'b' has %d elements", length_a, length_b));
}
}
/**
Asserts that a vector has a specific dimesion.
@par a The vector.
@par dimension The dimension.
*/
public func AssertDimension(array a, int dimension)
{
var dim = Dimension(a);
if (dim != dimension)
{
FatalError(Format("The function expects a vector of length %d, got length %d", dimension, dim));
}
}
/**
Asserts that a parameter is not nil.
@par parameter The parameter that is checked.
@par message [optional] a descriptive message for the parameter that is printed in the fatal error.
*/
public func AssertNotNil(parameter, string message)
{
if (parameter == nil)
{
if (!message) message = "parameter";
FatalError(Format("Expected %s that is not nil", message));
}
}
|