Пример #1
0
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);
		}
}
Пример #2
0
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]);
    }
}
Пример #3
0
// 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)))
Пример #4
0
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;
	}
}