void Orthographic::render_scene(const World& w) { RGBColor L; ViewPlane vp(w.vp); Ray ray; int depth = 0; Point2D pp; // sample point on a pixel int n = (int)sqrt((float)vp.num_samples); compute_direction(); compute_distance(); ray.d = dir; for (int r = 0; r < vp.vres; r++) // up for (int c = 0; c < vp.hres; c++) { // across L = black; for (int p = 0; p < n; p++) // up pixel for (int q = 0; q < n; q++) { // across pixel pp.x = vp.s * (c - 0.5 * vp.hres + (q + 0.5) / n); pp.y = vp.s * (r - 0.5 * vp.vres + (p + 0.5) / n); ray.o = Point3D(pp.x, pp.y, 0); L += w.tracer_ptr->trace_ray(ray, depth); } L /= vp.num_samples; //L *= exposure_time; w.display_pixel(r, c, L); } }
static void relocate_arcpoint(F_arc *arc, int x, int y, int movedpoint_num) { float xx, yy; F_pos p[3]; p[0] = arc->point[0]; p[1] = arc->point[1]; p[2] = arc->point[2]; p[movedpoint_num].x = x; p[movedpoint_num].y = y; if (compute_arccenter(p[0], p[1], p[2], &xx, &yy)) { arc->point[movedpoint_num].x = x; arc->point[movedpoint_num].y = y; arc->center.x = xx; arc->center.y = yy; arc->direction = compute_direction(p[0], p[1], p[2]); } }
// The wheel engages the GPIO PWM to create a 256 level "bar" on the 4 LEDs. // Rotating clockwise will gradually light up the bottom led in 64 steps, then // the LED above it will begin to glow, and so on until all 4 LEDs are fully lit. // Turning another clockwise round will have no effect. Turning anticlockwise one // round will make it gradually decrease the 256 level counter, thus causing the // bar to fade downwards until you hit 0. static void process_wheel(void) { unsigned char position_angle = p_qm_measure_data->p_rotor_slider_values[0]; static unsigned char previous_position_angle = 0; static int previous_leds_intensity_direction = DIRECTION_STABLE; int leds_intensity_direction; static bool first_call = true; // Special case for the first call. if(first_call == true) { // Just record the current angle; we'll determine the direction upon next call. first_call = false; previous_position_angle = position_angle; return; } // Compute the direction based on previous angle. leds_intensity_direction = compute_direction(previous_position_angle, position_angle); // Update for next call. previous_position_angle = position_angle; if(leds_intensity_direction == DIRECTION_STABLE) return; else if(leds_intensity_direction == DIRECTION_CLOCKWISE) { // Increase the intensity of the LEDs // Since we update also the nearby LEDs of the current LED, when there is a // change of direction we must insure consistency. if((previous_leds_intensity_direction != DIRECTION_CLOCKWISE)&&(current_led != IDX_LED0)) current_led--; // Update the duty cycle of the current LED while(1) { // Loop for safety: we always want to check the current duty cycle of a LED // before updating it. if(duty_cycles_per_led[current_led] == PWMA_MIN_DUTY_CYCLES) // Max intensity { // The current LED has already reached its max intensity if(current_led == (LED_COUNT-1)) // All LEDs are at max intensity return; else current_led++; // Switch focus to the next LED } else break; } duty_cycles_per_led[current_led] -= PWMA_DUTY_CYCLES_STEP; // If the current LED is over half of its max intensity, start to increase // the next LED intensity. Do this for all LEDs except the last. if(current_led != (LED_COUNT-1)) // The current LED is not the last { if(duty_cycles_per_led[current_led] <= (PWMA_MAX_DUTY_CYCLES - PWMA_MIN_DUTY_CYCLES)>>1) { if(duty_cycles_per_led[current_led+1] != PWMA_MIN_DUTY_CYCLES) duty_cycles_per_led[current_led+1] -= PWMA_DUTY_CYCLES_STEP; } } } else // ANTI-CLOCKWISE direction { // Decrease the intensity of the LEDs // Since we update also the nearby LEDs of the current LED, when there is a // change of direction we must insure consistency. if((previous_leds_intensity_direction != DIRECTION_ANTICLOCKWISE)&&(current_led != (LED_COUNT-1)))
void update_billiard_balls(billiard_ball *balls) { int i, j; double dx, dy, speed, direction; // variables for collisions // vector(x1 - x2) double delta_x, delta_y; // vector(v1 - v2) double dvx, dvy; // dot product, delta_length, an double dot_product, delta_length_square, an; // new velocities double new_v1x, new_v1y, new_v2x, new_v2y; // to prevent ball colliding each other the next time // we need to move the ball away if they will collide on each other again double slope, dcx, dcy; /* DEBUG */ #ifdef DEBUG if(balls == NULL) { perror("billiard_ball null pointer"); return; } #endif for(i = 0 ; i < BALL_COUNT ; i ++) { // printf("updating ball %i\n", i); dx = balls[i].dx; dy = balls[i].dy; // if the ball is not on the table, // which means it's in the bag // dont event bother updating it if(!balls[i].is_on_table) continue; // compute speed and direction speed = sqrt(dx * dx + dy * dy); direction = compute_direction(dx, dy); // apply friction force if(speed + BALL_FRICTION > 0) speed += BALL_FRICTION; else if(speed + BALL_FRICTION / 2 > 0) speed += BALL_FRICTION / 2; else if(speed + BALL_FRICTION / 8 > 0) speed += BALL_FRICTION / 8; else speed = 0; balls[i].dx = speed * cos(direction); balls[i].dy = speed * sin(direction); // if(speed == 0) continue; // collision detection -- border of the table if(is_ball_on_table_vertical_border(balls[i])) { balls[i].dx = -dx; balls[i].dx *= COLLISION_FRICTION; // to prevent ball sticking on the vertical border // if the ball is still on the vertical border next time // change the cx a little so that // the ball no longer stays on the vertical border while(is_ball_on_table_vertical_border(balls[i])) balls[i].cx += balls[i].dx >= 0 ? CP : -CP; } if(is_ball_on_table_horizontal_border(balls[i])) { balls[i].dy = -dy; balls[i].dy *= COLLISION_FRICTION; // to prevent ball sticking on the horizontal border // if the ball is still on the horizontal border next time // change the cy a little so that // the ball no longer stays on the horizontal border while(is_ball_on_table_horizontal_border(balls[i])) balls[i].cy += balls[i].dy >= 0 ? CP : -CP; } // check if the ball is in the bag if(is_ball_in_bag(balls[i])) { balls[i].dx = 0; balls[i].dy = 0; balls[i].is_on_table = 0; /* if(balls[i].number == 0) { // white ball got into the bag // reset the white ball and change turn balls[i].cx = 600; balls[i].cy = 400; balls[i].is_on_table = 1; } */ } // collision detection -- ball with ball for(j = 0 ; j < BALL_COUNT ; j ++) { if(i == j) continue; if(!balls[j].is_on_table) continue; if(is_ball_collided(balls[i], balls[j])) { //printf("ball %d collide with ball %i\n", i, j); //printf("before collision: "); //printf("ball %i(dx=%lf,dy=%lf), ball %i(dx=%lf,dy=%lf)\n", // i, balls[i].dx, balls[i].dy, j, balls[j].dx, balls[j].dy); /*************************************************************** * using the 2d collision formula on * http://en.wikipedia.org/wiki/Elastic_collision * * <v1'> = <v1> - (<v1-v2> dot <x1-x2>) / |<x1-x2>|^2 * <x1-x2> * <v2'> = <v2> - (<v2-v1> dot <x2-x1>) / |<x2-x1>|^2 * <x2-x1> ***************************************************************/ // new velocities computation // vector(x1 - x2) delta_x = balls[i].cx - balls[j].cx; delta_y = balls[i].cy - balls[j].cy; // vector(v1 - v2) dvx = balls[i].dx - balls[j].dx; dvy = balls[i].dy - balls[j].dy; // dot product vector(v1 - v2) dot vector(x1 - x2) dot_product = dvx * delta_x + dvy * delta_y; // denumerator delta_length_square = delta_x * delta_x + delta_y * delta_y; an = dot_product / delta_length_square; new_v1x = balls[i].dx - an * delta_x; new_v1y = balls[i].dy - an * delta_y; new_v2x = balls[j].dx + an * delta_x; new_v2y = balls[j].dy + an * delta_y; // assign new velocities to ball i and j balls[i].dx = new_v1x; balls[i].dy = new_v1y; balls[j].dx = new_v2x; balls[j].dy = new_v2y; // two ball collide with friction // which reduce both balls' velocity balls[i].dx *= COLLISION_FRICTION; balls[i].dy *= COLLISION_FRICTION; balls[j].dx *= COLLISION_FRICTION; balls[j].dy *= COLLISION_FRICTION; // play the collision audio al_play_sample(balls[i].collision_sound, BC_SOUND_GAIN, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); while(is_ball_collided(balls[i], balls[j])) { #ifdef DEBUG printf("shifting...\n"); #endif if(delta_x != 0) { slope = delta_y / delta_x; dcx = balls[i].cx > balls[j].cx ? CP : -CP; dcy = balls[i].cy > balls[j].cy ? slope * dx : -slope * dx; balls[i].cx += dcx; balls[i].cy += dcy; balls[j].cx -= dcx; balls[j].cy -= dcy; } else { dcy = balls[i].cy > balls[j].cy ? CP : -CP; balls[i].cy += dcy; balls[j].cy -= dcy; } } } } } for(i = 0 ; i < BALL_COUNT ; i ++) { // change the x, y position balls[i].cx += balls[i].dx; balls[i].cy += balls[i].dy; } }