# CORDIC Implementations From circular = 1 linear = 0 hyperbolic = -1 def ROM_lookup(iteration, coord_mode): if (coord_mode == circular): return math.degrees(math.atan(2**(-1*iteration))) elif (coord_mode == linear): return 2**(-1*iteration) elif (coord_mode == hyperbolic): return (math.atanh(2**(-1*iteration))) def rotation_mode(x, y, z, coord_mode, iterations): a = 0.607252935; # = 1/K x_val_list = [] y_val_list = [] z_val_list = [] iterations_list = [] i = 0; # Keeps count on number of iterations current_x = x # Value of X on ith iteration current_y = y # Value of Y on ith iteration current_z = z # Value of Z on ith iteration di = 0 if (coord_mode == hyperbolic): i = 1 else: i = 0 flag = 0 if (iterations > 0): while (i < iterations): if (current_z < 0): di = -1 else: di = +1 next_z = current_z - di * ROM_lookup(i, coord_mode) next_x = current_x - coord_mode * di * current_y * (2**(-1*i)) next_y = current_y + di * current_x * 2**(-1*i) current_x = next_x current_y = next_y current_z = next_z x_val_list.append(current_x) y_val_list.append(current_y) z_val_list.append(current_z) iterations_list.append(i) if (coord_mode == hyperbolic): if ((i != 4) & (i != 13) & (i!=40)): i = i+1 elif (flag == 0): flag = 1 elif (flag == 1): flag = 0 i = i+1 else: i = i+1 return { 'x':x_val_list, 'y':y_val_list, 'z':z_val_list, 'iteration':iterations_list, } def vector_mode(x, y, z, coord_mode, iterations): a = 1.2075; # = 1/K x_val_list = [] y_val_list = [] z_val_list = [] iterations_list = [] i = 0; # Keeps count on number of iterations current_x = x # Value of X on ith iteration current_y = y # Value of Y on ith iteration current_z = z # Value of Z on ith iteration di = 0 # This is neccesary since result for i=0 doesn't exists for hyperbolic # co-ordinate system. if (coord_mode == hyperbolic): i = 1 else: i = 0 flag = 0 if (iterations > 0): while (i < iterations): di = -1*math.copysign(1, current_y);#*current_x); next_x = current_x - coord_mode * di * current_y * (2**(-1*i)) next_y = current_y + di * current_x * 2**(-1*i) next_z = current_z - di * ROM_lookup(i, coord_mode) current_x = next_x current_y = next_y current_z = next_z x_val_list.append(current_x) y_val_list.append(current_y) z_val_list.append(current_z) iterations_list.append(i) if (coord_mode == hyperbolic): if ((i != 4) & (i != 13) & (i!=40)): i = i+1 elif (flag == 0): flag = 1 elif (flag == 1): flag = 0 i = i+1 else: i = i+1 return { 'x':x_val_list, 'y':y_val_list, 'z':z_val_list, 'iteration':iterations_list } Alternative in c: int i = 0; int iterations = 0; // Number of times to run the algorithm float arctanTable[iterations]; // in Radians float K = 0.6073; // K float v_x,v_y; // Vector v; x and y components for(i=0; i < iterations; i++) { arctanTable[i] = atan(pow(2,-i)); } float vnew_x; // To store the new value of x; for(i = 0; i < iterations; i++) { // If beta is negative, we need to do a counter-clockwise rotation: if( beta < 0) { vnew_x = v_x + (v_y*pow(2,-i)); v_y -= (v_x*pow(2,-i)); beta += arctanTable[i]; } // If beta is positive, we need to do a clockwise rotation: else { vnew_x = v_x - (v_y*pow(2,-i)); v_y += (v_x*pow(2,-i)); beta -= arctanTable[i]; } v_x = vnew_x; } v_x *= K; v_y *= K; # Vector Length > With VLENGTH being also expressible as dotproduct followed by scalar > sqrt, is it reasonable to have both normalisation as well as VLENGTH > as macro op fused sequences? Vector length would presumably involve dotting a vector with itself. The potential advantage I see is that the dot product might be tempted to read that vector twice; whereas the length would only read it once. If some other mechanism eliminates the duplicate read, they would be pretty well equivalent.