Eiffel Media API
Overview Cluster Class Classes Index      Previous Next      Top Features

em.video.collision_detection

Class EM_CIRCLE_COLLIDABLE


Direct ancestors

EM_COLLIDABLE

Creation

Features

Invariants

indexing

description

A circular bounding area for the collision detection.

date

$Date: 2005/10/23 16:34:13 $

revision

$Revision: 1.23 $

class

EM_CIRCLE_COLLIDABLE

inherit

EM_COLLIDABLE

create

make (a_center: EM_VECTOR_2D; a_radius: DOUBLE)

-- creates a collidable circle
-- to create a collidable dot, just set radius = 0

require
a_center_not_void: a_center /= Void
a_radius_non_negative: a_radius >= 0
ensure
radius_set: radius = a_radius
center_set: center.x = a_center.x and center.y = a_center.y
make_from_other (a_circle: EM_CIRCLE_COLLIDABLE)

-- creates a collidable circle which is equivalent to the given argument

-- (From EM_COLLIDABLE)

require
a_collidable_not_void: a_collidable /= Void
ensure then
radius_set: radius = a_circle.radius
center_set: center.x = a_circle.center.x and center.y = a_circle.center.y
make_from_circle (a_circle: EM_CIRCLE)

-- creates a collidable circle which is equivalent to the given argument

require
a_circle_not_void: a_circle /= Void
ensure
radius_set: radius = a_circle.radius
center_set: center.x = a_circle.x and center.y = a_circle.y
make_through_three_points (a_vector, b_vector, c_vector: EM_VECTOR_2D)

-- creates a circle, that goes through the 3 given points
-- if the 3 points are all aligned no such circle can be found and the unit circle is created
-- in that case the variable not_created will be set, to inform the client

require
a_vector_not_void: a_vector /= Void
b_vector_not_void: b_vector /= Void
c_vector_not_void: c_vector /= Void

feature -- Initialization

initialize

-- should be called upon creation, after the center was set

-- (From EM_COLLIDABLE)

require
center_set: center /= Void
ensure
color_set: color.red = 255 and color.green = 255 and color.blue = 255
make (a_center: EM_VECTOR_2D; a_radius: DOUBLE)

-- creates a collidable circle
-- to create a collidable dot, just set radius = 0

require
a_center_not_void: a_center /= Void
a_radius_non_negative: a_radius >= 0
ensure
radius_set: radius = a_radius
center_set: center.x = a_center.x and center.y = a_center.y
make_from_circle (a_circle: EM_CIRCLE)

-- creates a collidable circle which is equivalent to the given argument

require
a_circle_not_void: a_circle /= Void
ensure
radius_set: radius = a_circle.radius
center_set: center.x = a_circle.x and center.y = a_circle.y
make_from_other (a_circle: EM_CIRCLE_COLLIDABLE)

-- creates a collidable circle which is equivalent to the given argument

-- (From EM_COLLIDABLE)

require
a_collidable_not_void: a_collidable /= Void
ensure then
radius_set: radius = a_circle.radius
center_set: center.x = a_circle.center.x and center.y = a_circle.center.y
make_through_three_points (a_vector, b_vector, c_vector: EM_VECTOR_2D)

-- creates a circle, that goes through the 3 given points
-- if the 3 points are all aligned no such circle can be found and the unit circle is created
-- in that case the variable not_created will be set, to inform the client

require
a_vector_not_void: a_vector /= Void
b_vector_not_void: b_vector /= Void
c_vector_not_void: c_vector /= Void

feature -- Access

angle: DOUBLE

-- angle in radian, in which the bounding volume is rotated (0 is default), in [0 2pi]

-- (From EM_COLLIDABLE)

center: EM_VECTOR_2D

-- Center of the collidable objects circumcircle, also known as the circumcenter

-- (From EM_COLLIDABLE)

color: EM_COLOR

-- the color of the collidable, if drawn

-- (From EM_COLLIDABLE)

em_circle: EM_CIRCLE

-- returns an equivalent EM_CIRCLE object

holder: ANY

-- This option may be used, in order to know, who holds the collidable primitive

-- (From EM_COLLIDABLE)

ignore: BOOLEAN

-- true, if the object should be ignored from collision detection.
-- Please note, that this should only be used temporarily, if you don't want
-- to remove the object from the detector. If you wish not to use this
-- object anymore, please remove it from the detector.

-- (From EM_COLLIDABLE)

last_center: EM_VECTOR_2D

-- the center position since the last movement

-- (From EM_COLLIDABLE)

logger: EM_LOGGER

-- the logger object

-- (From EM_LOGGING)

not_created: BOOLEAN

-- will be set to true, if the circle could not be created correctly (in case of 3 aligned points in make_through_three_points)

radius: DOUBLE

-- Circumcircle radius of the collidable object, used for rough collision detection.
-- This is the maximal distance of any part of the object to center

-- (From EM_COLLIDABLE)

rotatable: BOOLEAN

-- a orthogan rectangle for example is not rotatable

-- (From EM_COLLIDABLE)

feature -- Element change

set_radius (v: DOUBLE)

-- sets radius

ensure
radius_set: radius = v
set_rotatable (v: BOOLEAN)

-- sets if the

-- (From EM_COLLIDABLE)

feature {EM_COLLISION_DETECTOR} -- Drawing

draw (a_surface: EM_SURFACE)

-- Draw Current to a_surface
-- The screen clipping is set with set_draw_clipping

-- (From EM_COLLIDABLE)

require
a_surface_not_void: a_surface /= Void

feature -- Element Change

move_by (an_x, a_y: DOUBLE)

-- moves the center by an_x, a_y

-- (From EM_COLLIDABLE)

process_changes

-- Process all changes to the collidable.
-- recomputes the radius and resets the value

-- (From EM_COLLIDABLE)

rotate_by (an_angle_in_radian: DOUBLE)

-- Rotates an object by a certain angle. positive means clockwise, because the y-axis of the screen is inverted!
-- rotates around center

-- (From EM_COLLIDABLE)

rotate_by_around_center (an_angle_in_radian: DOUBLE; a_center: EM_VECTOR_2D)

-- Rotates an object by a certain angle. positive means clockwise, because the y-axis of the screen is inverted!
-- rotates around a_center

-- (From EM_COLLIDABLE)

rotate_to (an_angle_in_radian: DOUBLE)

-- Rotates an object to a certain angle around the center.
-- the angle 0 is the angle in which the bounding volume was created and backed up
-- the backed up coordinates will always be used to generate the new ones, to
-- prevent deformation after a lot of rotations.

-- (From EM_COLLIDABLE)

rotate_to_around_center (an_angle_in_radian: DOUBLE; a_center: EM_VECTOR_2D)

-- Rotates an object to a certain angle around a_center.
-- the angle 0 is the angle in which the bounding volume was created and backed up
-- the backed up coordinates will always be used to generate the new ones, to
-- prevent deformation after a lot of rotations.

-- (From EM_COLLIDABLE)

set_center (a_center: EM_VECTOR_2D)

-- sets center, which also moves the whole object surrounding it

-- (From EM_COLLIDABLE)

require
a_center_not_void: a_center /= void
ensure
center_set: center.x = a_center.x and center.y = a_center.y
set_draw_circumcircle (v: BOOLEAN)

-- also draws the circumcircle of the collidable

-- (From EM_COLLIDABLE)

ensure
draw_circumcircle_set: draw_circumcircle = v
set_draw_circumcircle_color (c: EM_COLOR)

-- sets the circumcircle color

-- (From EM_COLLIDABLE)

require
color_not_void: c /= Void
ensure
circumcircle_color_set: draw_circumcircle_color = c
set_draw_clipping (top_left_corner: EM_VECTOR_2D; a_zoom_factor: DOUBLE)

-- This sets the clipping for the part to draw
-- The first argument is the top left corner of the screen.
-- for example if we want an object, that is situated at (5000, 1000), the
-- clipping should be moved to an appropriate position e.g. (4800, 800)
-- All objects outside of the clipping will not be displayed

-- (From EM_COLLIDABLE)

require
corner_not_void: top_left_corner /= void
factor_valid: a_zoom_factor > 0
set_draw_color (a_color: EM_COLOR)

-- sets the color of the collidable, if draw is used

-- (From EM_COLLIDABLE)

require
a_color_not_void: a_color /= Void
ensure
color_set: a_color = color
set_draw_filled (v: BOOLEAN)

-- sets to filled draw mode

-- (From EM_COLLIDABLE)

ensure
filled_set: filled = v
set_holder (v: ANY)

-- assigns the holder to a certain reference

-- (From EM_COLLIDABLE)

ensure
holder = v
set_ignore (v: BOOLEAN)

-- sets if an item should be temporarily ignored for collision detection

-- (From EM_COLLIDABLE)

ensure
ignore = v
set_x_y (x_position, y_position: DOUBLE)

-- sets the center to (x,y)

-- (From EM_COLLIDABLE)

ensure
last_center_set: last_center.x = old center.x and last_center.y = old center.y
center_set: center.x = x_position and center.y = y_position

feature -- Status Report

collides_between_step (a_collidable: EM_COLLIDABLE; depth, search_depth: INTEGER): DOUBLE

-- search of collisions in between steps.
-- Performance: O (2^d * collision_check_time)
-- returns if they ever collide and the first time of collision found.

-- (From EM_COLLIDABLE)

require
doesnt_collide_at_last_step: not collides_with_at_time (a_collidable, 0)
doesnt_collide: not collides_with (a_collidable)
ensure
result_in_range: Result >= 0 and Result < 1
collides_with (a_collidable: EM_COLLIDABLE): BOOLEAN

-- checks if two objects collide

-- (From EM_COLLIDABLE)

require
a_collidable_void: a_collidable /= Void
collides_with_depth (a_collidable: EM_COLLIDABLE; d: INTEGER): EM_PAIR [BOOLEAN, DOUBLE]

-- searches the first collision point of 2 collidables with search depth d.
-- returns a pair, if no collision was found, returns [false, 0]
-- otherwise true and the time at which the first collision happened, between 0 and 1

-- (From EM_COLLIDABLE)

require
a_collidable_not_void: a_collidable /= Void
depth_valid: d >= 0
intersection_points (a_collidable: EM_COLLIDABLE): DS_LINKED_LIST [EM_PAIR [EM_VECTOR_2D, EM_DIRECTION_2D]]

-- returns the average collision point and tangential direction of the 2 collidable objects current and a_collidable
-- if no intersection points were found, returns Void

-- (From EM_COLLIDABLE)

require
a_collidable_void: a_collidable /= Void
max_distance_to_position (a_position: EM_VECTOR_2D): DOUBLE

-- computes the maximal distance to a certain position.
-- this is used to compute the radius of compositions of collidables

-- (From EM_COLLIDABLE)

require
a_position_not_void: a_position /= Void

feature -- Computation

area: DOUBLE

-- area of the collidable in pixel^2

-- (From EM_COLLIDABLE)

center_of_mass: EM_VECTOR_2D

-- returns the center of mass (also known as the centroid)

-- (From EM_COLLIDABLE)

collides_with_at_time (a_collidable: EM_COLLIDABLE; t: DOUBLE): BOOLEAN

-- checks if 2 collidables collided at time t

-- (From EM_COLLIDABLE)

require
a_collidable_not_void: a_collidable /= Void
t_valid: t >= 0 and t <= 1
duplicate: like Current

-- returns an equivalent copy of the collidable (just the position and borders)

-- (From EM_COLLIDABLE)

duplicate_circle: EM_CIRCLE_COLLIDABLE

-- returns an equivalent copy of the object as a EM_CIRCLE_COLLIDABLE

feature {EM_COLLIDABLE} -- Implementation

clipping: EM_VECTOR_2D

-- the top left corner. for more details see set_draw_clipping

-- (From EM_COLLIDABLE)

collides_between_step_implementation (a_collidable: EM_COLLIDABLE; d: INTEGER; a,b: DOUBLE): DOUBLE

-- recursive search for the first collision point (if any)
-- returns the time of the first collision (0 < time < 1)
-- returns 0, if no collision was found

-- (From EM_COLLIDABLE)

require
doesnt_collide_at_last_step: not collides_with_at_time (a_collidable, 0)
doesnt_collide: not collides_with (a_collidable)
collides_with_depth_implementation (a_collidable: EM_COLLIDABLE; d: INTEGER; a, b: DOUBLE): DOUBLE

-- recursive search of collision points. This function is called by collides_with_depth
-- requires the collidables to collide at the end (b=1) as a precondition (not tested)

-- (From EM_COLLIDABLE)

require
a_collidable_not_void: a_collidable /= Void
a_and_b_valid: b > a and a >= 0 and b <= 1
d_non_negative: d >= 0
draw_circumcircle: BOOLEAN

-- true, if the circumcircle should be drawn

-- (From EM_COLLIDABLE)

draw_circumcircle_color: EM_COLOR

-- color of the circumcircle

-- (From EM_COLLIDABLE)

filled: BOOLEAN

-- true, if the collidable should be drawn filled

-- (From EM_COLLIDABLE)

turn (an_angle: DOUBLE)

-- turns a bounding area TO a certain angle. this will be called from rotate_to or rotate_by

-- (From EM_COLLIDABLE)

zoom_factor: DOUBLE

-- the zoom factor from the clipping point

-- (From EM_COLLIDABLE)

invariant

radius_positive: radius >= 0
angle_is_normalized: angle = normalized_angle (angle)
logger_not_void: logger /= Void
clipping_set: clipping.x = 0 and clipping.y = 0
zoom_factor_set: zoom_factor = 1
last_center_not_void: last_center /= Void

-- From ANY
reflexive_equality: standard_is_equal (Current)
reflexive_conformance: conforms_to (Current)

-- From EM_LOGGING
logger_created: logger /= void

end