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

em.video.collision_detection

Class EM_COLLIDABLE


Direct ancestors

EM_COLLISION_IMPLEMENTATION, EM_LOGGING

Known direct descendants

EM_RECTANGLE_COLLIDABLE, EM_CIRCLE_COLLIDABLE, EM_POLYGON_CONVEX_COLLIDABLE, EM_COLLIDABLE_COMPOSITION

Features

Invariants

indexing

description

Objects that should be detected by the collision detector EM_COLLISION_DETECTOR
have to inherit from EM_COLLIDABLE

The implemented collidables are
EM_CIRCLE_COLLIDABLE
EM_RECTANGLE_COLLIDABLE
EM_POLYGON_COLLIDABLE
EM_COLLIDABLE_COMPOSITION

date

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

revision

$Revision: 1.22 $

deferred class

EM_COLLIDABLE

inherit

EM_LOGGING

feature -- Initialization

initialize

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

require
center_set: center /= Void
ensure
color_set: color.red = 255 and color.green = 255 and color.blue = 255
make_from_other (a_collidable: EM_COLLIDABLE)

-- copies a collidable

require
a_collidable_not_void: a_collidable /= Void

feature -- Access

angle: DOUBLE

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

center: EM_VECTOR_2D

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

color: EM_COLOR

-- the color of the collidable, if drawn

holder: ANY

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

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.

last_center: EM_VECTOR_2D

-- the center position since the last movement

logger: EM_LOGGER

-- the logger object

-- (From EM_LOGGING)

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

rotatable: BOOLEAN

-- a orthogan rectangle for example is not rotatable

feature -- Drawing

draw (a_surface: EM_SURFACE)

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

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

process_changes

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

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

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

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.

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.

set_center (a_center: EM_VECTOR_2D)

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

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

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

-- sets the circumcircle color

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

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

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

-- sets to filled draw mode

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

-- assigns the holder to a certain reference

ensure
holder = v
set_ignore (v: BOOLEAN)

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

ensure
ignore = v
set_rotatable (v: BOOLEAN)

-- sets if the object is rotatable

set_x_y (x_position, y_position: DOUBLE)

-- sets the center to (x,y)

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.

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

-- Rough collision detection of circumcircle

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

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
-- in case of concave objects (compositions of convex objects) a collision may be returned for each element of the
-- composition. The same 2 collidables can have multiple collision points.

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

require
a_position_not_void: a_position /= Void

feature -- Computation

area: DOUBLE

-- area of the collidable in pixel^2

center_of_mass: EM_VECTOR_2D

-- computes and returns the center of mass

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

-- checks if 2 collidables collided at time t

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)

feature {EM_COLLIDABLE} -- Implementation

clipping: EM_VECTOR_2D

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

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

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)

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

draw_circumcircle_color: EM_COLOR

-- color of the circumcircle

filled: BOOLEAN

-- true, if the collidable should be drawn filled

turn (an_angle: DOUBLE)

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

turn_around_center (an_angle: DOUBLE; a_center: EM_VECTOR_2D)

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

require
a_center_not_void: a_center /= Void
zoom_factor: DOUBLE

-- the zoom factor from the clipping point

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