static int cmatrix_self_gram_schmidt_process(matrix_t *m, int x, int y, int w, int h) { int i, j, k; complex_t u, v, *u_vec; complex_t c, d, tmp; u_vec = (complex_t *)malloc(h * sizeof(complex_t)); // Step 1. Let U0 = V0 // nothing to do for (i = x + 1; i < x + w; i++) { // U(i) = V(i) - proj_{U(0)}(V(i)) - proj_{U(2)}(V(i)) - .... // proj_{U}(V) = ((U * V) / (U * U)) * U for (k = 0; k < h; k++) cmatrix_read_value(&u_vec[k], m, i, y + k); for (j = x; j < i; j++) { c.real = c.imag = d.real = d.imag = 0; for (k = y; k < y + h; k++) { cmatrix_read_value(&v, m, i, k); cmatrix_read_value(&u, m, j, k); complex_add_complex_multiply_complex(&c, &u, complex_conjugate(&tmp, &v)); complex_add_complex_multiply_complex(&d, &u, complex_conjugate(&tmp, &u)); } complex_divide_complex(&c, &d); for (k = y; k < y + h; k++) { cmatrix_read_value(&u, m, j, k); complex_subtract_complex_multiply_complex(&u_vec[k-y], &u, &c); } } for (k = 0; k < h; k++) cmatrix_put_value(u_vec[k], m, i, y + k); if (cmatrix_is_zero(m, i, y, 1, y +h)) break; } free(u_vec); // normalization for (j = x; j < i; j++) { d.real = d.imag = 0; for (k = y; k < y + h; k++) { cmatrix_read_value(&u, m, j, k); complex_add_complex_multiply_complex(&d, &u, complex_conjugate(&tmp, &u)); } complex_copy_complex_sqrt(&c, &d); for (k = y; k < y + h; k++) { cmatrix_read_value(&u, m, j, k); complex_divide_complex(&u, &c); cmatrix_put_value(u, m, j, k); } } return i - x; }
void Ship::update(InputButtons::Bitset& input, GameState& game_state) { static const float TURNING_SPEED = radiansFromDegrees(5.0f); static const vec2 turning_vel = complex_from_angle(TURNING_SPEED); anim_flags.reset(); if (input.test(InputButtons::LEFT)) { rb.angular_vel = complex_conjugate(turning_vel); anim_flags.set(AnimationFlags::THRUST_CCW); } if (input.test(InputButtons::RIGHT)) { rb.angular_vel = turning_vel; anim_flags.set(AnimationFlags::THRUST_CW); } if (input.test(InputButtons::LEFT) == input.test(InputButtons::RIGHT)) { rb.angular_vel = complex_1; Position mouse_pos = game_state.camera.inverse_transform( mvec2(static_cast<float>(game_state.mouse_x), static_cast<float>(game_state.mouse_y))); vec2 mouse_orientation = normalized(mouse_pos - rb.pos); rb.orientation = rotateTowards(rb.orientation, mouse_orientation, TURNING_SPEED); } if (input.test(InputButtons::BRAKE)) { rb.vel = 0.96f * rb.vel; anim_flags.set(AnimationFlags::INERTIAL_BRAKE); } else if (input.test(InputButtons::THRUST)) { vec2 accel = 0.05f * rb.orientation; rb.vel = rb.vel + accel; anim_flags.set(AnimationFlags::THRUST_FORWARD); } if (input.test(InputButtons::SHOOT) && shoot_cooldown == 0) { Bullet bullet; bullet.physp.pos = rb.pos; bullet.orientation = rb.orientation; bullet.physp.vel = rb.vel + 4.0f * rb.orientation; bullet.img = img_bullet; game_state.bullets.push_back(bullet); shoot_cooldown = 5; } if (shoot_cooldown > 0) { --shoot_cooldown; } shield.update(); rb.update(); }
void compute_fourth_corner( Complex corner[4], VertexIndex missing_corner, Orientation orientation, ComplexWithLog cwl[3]) { int i; VertexIndex v[4]; Complex z[4], cross_ratio, diff20, diff21, numerator, denominator; /* * Given the locations on the sphere at infinity in * the upper half space model of three of a Tetrahedron's * four ideal vertices, compute_fourth_corner() computes * the location of the remaining corner. * * corner[4] is the array which contains the three known * corners, and into which the fourth will be * written. * * missing_corner is the index of the unknown corner. * * orientation is the Orientation with which the Tetrahedron * is currently being viewed. * * cwl[3] describes the shape of the Tetrahedron. */ /* * Set up an indexing scheme v[] for the vertices. * * If some vertex (!= missing_corner) is positioned at infinity, let its * index be v0. Otherwise choose v0 arbitrarily. Then choose * v2 and v3 so that the Tetrahedron looks right_handed relative * to the v[]. */ v[3] = missing_corner; v[0] = ! missing_corner; for (i = 0; i < 4; i++) if (i != missing_corner && complex_infinite(corner[i])) v[0] = i; if (orientation == right_handed) { v[1] = remaining_face[v[3]][v[0]]; v[2] = remaining_face[v[0]][v[3]]; } else { v[1] = remaining_face[v[0]][v[3]]; v[2] = remaining_face[v[3]][v[0]]; } /* * Let z[i] be the location of v[i]. * The z[i] are known for i < 3, unknown for i == 3. */ for (i = 0; i < 3; i++) z[i] = corner[v[i]]; /* * Note the cross_ratio at the edge connecting v0 to v1. */ cross_ratio = cwl[edge3_between_faces[v[0]][v[1]]].rect; if (orientation == left_handed) cross_ratio = complex_conjugate(complex_div(One, cross_ratio)); /* * The cross ratio is defined as * * (z3 - z1) (z2 - z0) * cross_ratio = ----------------------- * (z2 - z1) (z3 - z0) * * Solve for z3. * * z1*(z2 - z0) - cross_ratio*z0*(z2 - z1) * z3 = ----------------------------------------- * (z2 - z0) - cross_ratio*(z2 - z1) * * If z0 is infinite, this reduces to * * z3 = z1 + cross_ratio * (z2 - z1) * * which makes sense geometrically. */ if (complex_infinite(z[0]) == TRUE) z[3] = complex_plus( z[1], complex_mult( cross_ratio, complex_minus(z[2], z[1]) ) ); else { diff20 = complex_minus(z[2], z[0]); diff21 = complex_minus(z[2], z[1]); numerator = complex_minus( complex_mult(z[1], diff20), complex_mult( cross_ratio, complex_mult(z[0], diff21) ) ); denominator = complex_minus( diff20, complex_mult(cross_ratio, diff21) ); z[3] = complex_div(numerator, denominator); /* will handle division by Zero correctly */ } corner[missing_corner] = z[3]; }
bool collideCircleRectangle(vec2 circle_position, float circle_radius, vec2 rect_size, vec2 rect_orientation) { vec2 rotated_circle = complex_mul(circle_position, complex_conjugate(rect_orientation)); return collideCircleAARectangle(rotated_circle, circle_radius, rect_size); }