#define vectorCopy // Vector = vectorCreateCopy(set1, id1, set2, id2) // copies a vector from set1 with id1 to set2 with id2 // returns false when the vector cannot be copied, otherwise true var set1, dimensions1, vectorId1, set2, dimensions2, vectorId2, i; set1 = argument0; dimensions1 = ds_list_find_value(set1, 0); vectorId1 = argument1; set2 = argument2; dimensions2 = ds_list_find_index(set2, 0); vectorId2 = argument3; if (dimensions1 != dimensions2) { return false; } // copies vector for (i = 0; i < dimensions1; i += 1) { ds_list_replace(set2, 2 + (dimensions1 + 1) * vectorId2 + i, ds_list_find_value(set1, 2 + (dimensions1 + 1) * vectorId1 + i) ); } return true; #define vectorCreate // Vector = vectorCreate(set, dimensions) // adds a vector with the corresponding dimensions to the vectorset // tries to find empty places in the ds_list, otherwise extends the list var set, dimensions, i, place; set = argument0; dimensions = ds_list_find_value(set, 0); place = ds_list_find_index(set, "empty"); if (place < 0) { // no empty vector places ds_list_add(set, "notempty"); for (i = 0; i < dimensions; i += 1) { ds_list_add(set, argument[i + 1]); } return round((ds_list_size(set) - dimensions - 2) / (dimensions + 1)); } else { // empty vector place, use it! ds_list_replace(set, place, "notempty"); for (i = 0; i < dimensions; i += 1) { ds_list_replace(set, place + i + 1, argument[i + 1]); } return round((place - 1) / (dimensions + 1)); } #define vectorCreateFast // Vector = vectorCreateFast(set, dimensions) // adds a vector with the corresponding dimensions to the vectorset // does not use empty spaces for fast processing at the cost of increased memory usage var set, dimensions, i, place; set = argument0; dimensions = ds_list_find_value(set, 0); ds_list_add(set, "notempty"); for (i = 0; i < dimensions; i += 1) { ds_list_add(set, argument[i + 1]); } return round((ds_list_size(set) - dimensions - 2) / (dimensions + 1)); #define vectorCreateZero // Vector = vectorCreate(set) // adds a zerovector to the vectorlist // tries to find empty places in the ds_list, otherwise extends the list var set, dimensions, i, place; set = argument0; dimensions = ds_list_find_value(set, 0); place = ds_list_find_index(set, "empty"); if (place < 0) { // no empty vector places ds_list_add(set, "notempty"); for (i = 0; i < dimensions; i += 1) { ds_list_add(set, 0); } return round((ds_list_size(set) - dimensions - 2) / (dimensions + 1)); } else { // empty vector place, use it! ds_list_replace(set, place, "notempty"); for (i = 0; i < dimensions; i += 1) { ds_list_replace(set, place + i + 1, 0); } return round((place - 1) / (dimensions + 1)); } #define vectorCross // vectorDot(set, id1, id2, idCross) // sets the vector with id = idCross to the cross-product of vectors id1 and id2 // returns false if cross-product is a zerovector or this set is not a 3-dimensional vector set, otherwise true var set, dimensions, vectorId1, vectorId1, vectorIdC, c1, c2, c3, u1, u2, u3, v1, v2, v3; set = argument0; dimensions = ds_list_find_value(set, 0); vectorId1 = argument1; vectorId2 = argument2; vectorIdC = argument3; // I have no plans on making a 7D cross product script, who the f--k needs that?? if (dimensions != 3) { return false; } // get components u1 = ds_list_find_value(set, 2 + (dimensions + 1) * vectorId1 + 0); u2 = ds_list_find_value(set, 2 + (dimensions + 1) * vectorId1 + 1); u3 = ds_list_find_value(set, 2 + (dimensions + 1) * vectorId1 + 2); v1 = ds_list_find_value(set, 2 + (dimensions + 1) * vectorId2 + 0); v2 = ds_list_find_value(set, 2 + (dimensions + 1) * vectorId2 + 1); v3 = ds_list_find_value(set, 2 + (dimensions + 1) * vectorId2 + 2); // calculate new vector c1 = u2 * v3 - u3 * v2; c2 = u3 * v1 - u1 * v3; c3 = u1 * v2 - u2 * v1; // set cross-product vector ds_list_replace(set, 2 + (dimensions + 1) * vectorIdC + 0, c1); ds_list_replace(set, 2 + (dimensions + 1) * vectorIdC + 1, c2); ds_list_replace(set, 2 + (dimensions + 1) * vectorIdC + 2, c3); // return false if zerovector if (c1 == 0 && c2 == 0 && c3 == 0) { return false; } return true; #define vectorDot // value = vectorDot(set, id1, id2) // returns the dot-product of vectors id1 and id2 var set, dimensions, vectorId1, vectorId1, dotValue, i; set = argument0; dimensions = ds_list_find_value(set, 0); vectorId1 = argument1; vectorId2 = argument2; dotValue = 0; // calculate dot-product for (i = 0; i < dimensions; i += 1) { dotValue += ds_list_find_value(set, 2 + (dimensions + 1) * vectorId1 + i) * ds_list_find_value(set, 2 + (dimensions + 1) * vectorId2 + i); } return dotValue; #define vectorFree // vectorDestroy(set, id) // frees the memory of the vector with this id // (does not unset the components, only allows to reuse the memory) var set, dimensions, vectorId, component; set = argument0; dimensions = ds_list_find_value(set, 0); vectorId = argument1; ds_list_replace(set, 1 + (dimensions + 1) * vectorId, "empty"); #define vectorGet // value = vectorGet(set, id, n) // returns the n-th component of the vector var set, dimensions, vectorId, component; set = argument0; dimensions = ds_list_find_value(set, 0); vectorId = argument1; component = abs(argument2); return ds_list_find_value(set, 2 + (dimensions + 1) * vectorId + component); #define vectorLength // value = vectorLength(set, id) // returns the length of the vector with this id var set, dimensions, vectorId, value, squareSum, i; set = argument0; dimensions = ds_list_find_value(set, 0); vectorId = argument1; squareSum = 0; for (i = 0; i < dimensions; i += 1) { // cheaper than calling sqr (unless in GM:Studio I guess..) value = ds_list_find_value(set, 2 + (dimensions + 1) * vectorId + i); squareSum += value * value; } return sqrt(squareSum); #define vectorScale // vectorScale(set, id1, id2, scalar) // scales the vector with the given scalar and stores it in the vector with id = id2 var set, dimensions, vectorId1, vectorId2, scalar, i; set = argument0; dimensions = ds_list_find_value(set, 0); vectorId1 = argument1; vectorId2 = argument2; scalar = argument3; // scales the vector for (i = 0; i < dimensions; i += 1) { ds_list_replace(set, 2 + (dimensions + 1) * vectorId2 + i, ds_list_find_value(set, 2 + (dimensions + 1) * vectorId1 + i) * scalar ); } #define vectorSet // vectorSet(set, id, components) // returns the dot-product of vectors id1 and id2 var set, dimensions, vectorId, i; set = argument0; dimensions = ds_list_find_value(set, 0); vectorId = argument1; // set new components for (i = 0; i < dimensions; i += 1) { ds_list_replace(set, 2 + (dimensions + 1) * vectorId + i, argument[i + 2]); } #define vectorSetCreate // VectorSet = vectorSetCreate(n) // creates a vector set for vectors with n dimensions (max. 15 dimensions) and returns it var set, dimensions; set = ds_list_create(); dimensions = argument0; ds_list_add(set, dimensions); return set; /* data structure design: * * 0: number of dimensions * [ for every vector ] * id + 0: "empty" or "notempty" to indicate whether or not the vector-id is used * id + 1: first component * ... * id + n: last component */ #define vectorSetDestroy // vectorSetDestroy(set) // destroys the vector set var set; set = argument0; ds_list_destroy(set); #define vectorShowDebug // vectorShowDebug(set, id) // shows a messagebox with the vector's information var set, dimensions, vectorId, i, str; set = argument0; dimensions = ds_list_find_value(set, 0); vectorId = argument1; str = "VectorSet \#" + string(set) + "#Vector \#" + string(vectorId) + "#Dimensions: " + string(dimensions) + "#- - - - - -"; for (i = 0; i < dimensions; i += 1) { str += "#" + string(i) + ": "; str += string(ds_list_find_value(set, 2 + (dimensions + 1) * vectorId + i)); } str += "#- - - - - -#Length: " + string(vectorLength(set, vectorId)); show_message(str); #define vectorSubstract // vectorSubstract(set, id1, id2, idSum) // sets the vector with id = idSum to the vector you get when substracting id = id2 from id = id1 var set, dimensions, vectorId1, vectorId1, vectorIdS, i, value; set = argument0; dimensions = ds_list_find_value(set, 0); vectorId1 = argument1; vectorId2 = argument2; vectorIdS = argument3; for (i = 0; i < dimensions; i += 1) { ds_list_replace(set, 2 + (dimensions + 1) * vectorIdS + i, ds_list_find_value(set, 2 + (dimensions + 1) * vectorId1 + i) - ds_list_find_value(set, 2 + (dimensions + 1) * vectorId2 + i) ); } #define vectorSum // vectorSum(set, id1, id2, idSum) // sets the vector with id = idSum to the sumvector of id1 and id2 var set, dimensions, vectorId1, vectorId1, vectorIdS, i, value; set = argument0; dimensions = ds_list_find_value(set, 0); vectorId1 = argument1; vectorId2 = argument2; vectorIdS = argument3; for (i = 0; i < dimensions; i += 1) { ds_list_replace(set, 2 + (dimensions + 1) * vectorIdS + i, ds_list_find_value(set, 2 + (dimensions + 1) * vectorId1 + i) + ds_list_find_value(set, 2 + (dimensions + 1) * vectorId2 + i) ); } #define vectorUnit // vectorUnit(set, id1, id2) // normalizes the vector with id = id1, stores in vector with id = id2 // zerovectors remain zerovectors var set, dimensions, vectorId1, vectorId2, length, i; set = argument0; dimensions = ds_list_find_value(set, 0); vectorId1 = argument1; vectorId2 = argument2; // no need to re-invent the wheel length = vectorLength(set, vectorId1); if (length != 0) { // normalize by dividing the components by the total lenght for (i = 0; i < dimensions; i += 1) { ds_list_replace(set, 2 + (dimensions + 1) * vectorId2 + i, ds_list_find_value(set, 2 + (dimensions + 1) * vectorId1 + i) / length ); } } else { // set zerovector for (i = 0; i < dimensions; i += 1) { ds_list_replace(set, 2 + (dimensions + 1) * vectorId2 + i, 0); } }