# Common math/spatial operations # Math3D.tz (c) 2010 Jacob Schrum. # See Simulation.tz for more copyright information @include "Abstract.tz" @include "Constants.tz" @define VECTOR_EPSILON 0.001. Abstract : Math3D { # Trivial archiving, since state is simple + to archive: return 1. + to dearchive: return 1. + to get-random-spot-in-bin: return (random[(2 * (HALF_WALL_LENGTH - WALL_BUFFER),0,2 * (HALF_WALL_LENGTH - WALL_BUFFER))] + (-(HALF_WALL_LENGTH - WALL_BUFFER),1,-(HALF_WALL_LENGTH - WALL_BUFFER))). + to get-random-unit-vector: v (vector). v = random[ (2.0, 0.0, 2.0) ] - (1.0, 0.0, 1.0). v = v / |v|. return v. + to get-turn-matrix with-angle angle (double): c (double). s (double). c = cos(angle). s = sin(angle). return [(c,0,-s), (0,1,0), (s,0,c)]. + to signed-angle-difference between vector1 (vector) and vector2 (vector): theAngle (double). positiveTurn (vector). negativeTurn (vector). if (|vector1| == 0) || (|vector2| == 0) : return 0. vector1 = vector1/|vector1|. vector2 = vector2/|vector2|. if vector1 == vector2 : return 0. if (|vector1::x + vector2::x| < VECTOR_EPSILON) && (|vector1::z + vector2::z| < VECTOR_EPSILON) : return PI. theAngle = angle(vector1, vector2). if isnan(theAngle) : { print vector1. print vector2. return 0. } positiveTurn = (self get-turn-matrix with-angle theAngle) * vector1. negativeTurn = (self get-turn-matrix with-angle (-theAngle)) * vector1. if (angle(vector2, positiveTurn)) < (angle(vector2, negativeTurn)) : return (-theAngle). else return theAngle. # vals: list of values + to summation of vals (list): i (int). sum (double). sum = 0.0. for i = 0, i < |vals|, i++ : sum += vals{i}. return sum. # vals: list of values # - vals has at least one element + to list-min of vals (list): i (int). minVal (double). minVal = (vals{0}). for i = 1, i < |vals|, i++ : minVal = min(minVal, vals{i}). return minVal. # vals: list of values # - vals has at least one element + to list-max of vals (list): i (int). maxVal (double). maxVal = (vals{0}). for i = 1, i < |vals|, i++ : maxVal = max(maxVal, vals{i}). return maxVal. # vals: list of values + to list-average of vals (list): i (int). average (double). average = 0.0. for i = 0, i < |vals|, i++ : average += (vals{i} - average)/(i + 1.0). return average. + to sigmoid-scale of x (double) border b (double): return (2 / (1 + (E ^ (-2 * (x / b))))) - 1. # |v1| == |v2| + to get-euclidean-distance between v1 (list) and v2 (list): i (int). sum (double). sum = 0. for i = 0, i < |v1|, i++ : { sum += (v1{i} - v2{i})^2. } return (sqrt(sum)). }