class QUANTUM_BALL_ANIMATION
Quantum ball animation
note
description: "Quantum ball animation"
author: "Finnian Reilly"
copyright: "Copyright (c) 2001-2022 Finnian Reilly"
contact: "finnian at eiffel hyphen loop dot com"
license: "MIT license (See: en.wikipedia.org/wiki/MIT_License)"
date: "2022-11-15 19:56:03 GMT (Tuesday 15th November 2022)"
revision: "8"
class
QUANTUM_BALL_ANIMATION
inherit
EL_MAIN_THREAD_REGULAR_INTERVAL_EVENT_CONSUMER
rename
make_default as make_event_consumer,
on_event as redraw,
stop as stop_consumer
export
{NONE} all
redefine
on_events_start
end
EL_LOGGED_EVENT_COUNTER
EL_LOGGED_REGULAR_INTERVAL_EVENT_PROCESSOR
undefine
default_create
end
MODEL_WORLD_TILER
rename
model as world
undefine
default_create
end
EV_FONT_CONSTANTS
undefine
default_create
end
DOUBLE_MATH
rename
log as logarithm
undefine
default_create
end
EL_MODULE_IMAGE
EL_MODULE_ARGS
EL_MODULE_LOG
create
make
feature {NONE} -- Initialization
make
--
local
pos: EV_COORDINATE
do
make_event_consumer
-- make_event_producer (Current, (1000 / Frames_per_sec).rounded)
make_event_producer ("Animation timer", Current, (1000 / Frames_per_sec).rounded)
-- make_bounded_loop_event_producer (Current, "Ball animation timer", (1000 / Frames_per_sec).rounded, 3)
radius := 70
millisecs_per_cycle := 4100
create world
create model_cell.make_with_world (world)
model_cell.set_world_border (10)
model_cell.set_minimum_size (Background_tile.width * 3, Background_tile.height * 3)
create lesson_label.make_with_text ("Hydrogen Atom")
lesson_label.set_point_position (7, 7)
lesson_label.set_font (create {EV_FONT}.make_with_values (Family_roman, Weight_bold, Shape_regular, 28))
lesson_label.set_foreground_color (Colors.Dark_red)
world.extend (lesson_label)
create lesson_label.make_with_text ("2p electron orbital")
lesson_label.set_point_position (15, 40)
lesson_label.set_font (create {EV_FONT}.make_with_values (Family_roman, Weight_regular, Shape_regular, 20))
world.extend (lesson_label)
create pos.make_with_position ((Background_tile.width * 2.3).rounded, (Background_tile.height * 0.16).rounded)
create proton.make_with_pixmap (Soccer_ball_image)
world.extend (proton)
proton.set_x_y (model_cell.width // 2, model_cell.height // 2)
set_position (0)
create electron.make
world.extend (electron)
electron.set_x_y (x_pos, y_pos)
add_tiles (Background_tile)
end
feature -- Access
model_cell: QUANTUM_BALL_ANIMATION_AREA_CELL
world: EV_MODEL_WORLD
electron: MODEL_ELECTRON
proton: EV_MODEL_PICTURE
label: EV_MODEL_TEXT
lesson_label: EV_MODEL_TEXT
feature -- Element change
set_position (a_elapsed_millisecs: INTEGER)
--
local
proportion_x, proportion_y, proportion_radius, radius_variability: DOUBLE
new_angle: DOUBLE
do
new_angle := radians_per_millisec * a_elapsed_millisecs
proportion_x := sine (new_angle)
proportion_y := cosine (new_angle / 2)
z_acceleration_proportion := z_acceleration_proportion + 0.001
proportion_z := cosine (new_angle * z_acceleration_proportion)
radius_variability :=0.3 + sine (0.5 * new_angle) * 0.2
proportion_radius := 0.3 + sine (radius_variability * new_angle)
x_pos := model_cell.width // 2 - (model_cell.width // 3 * proportion_x * proportion_radius).rounded
y_pos := model_cell.height // 2 - (model_cell.height // 3 * proportion_y * proportion_radius).rounded
end
feature {NONE} -- Implementation
count: INTEGER
do
Result := event.count
end
elapsed_millisecs: INTEGER
do
Result := event.elapsed_millisecs
end
redraw
--
local
previous_pos_flag: BOOLEAN; size_proportion: DOUBLE
do
log_event
set_position (elapsed_millisecs)
electron.set_x_y (x_pos, y_pos)
size_proportion := 0.2 + 0.8 * (proportion_z + 1) / 2.0
electron.scale (size_proportion)
previous_pos_flag := is_electron_behind_proton
is_electron_behind_proton := size_proportion < 0.7 and electron.bounding_box.intersects (proton.bounding_box)
if previous_pos_flag /= is_electron_behind_proton then
world.finish
world.swap (world.index - 1)
end
model_cell.projector.full_project
if millisecs_per_cycle > 1000.0 then
millisecs_per_cycle := millisecs_per_cycle - 0.4
end
end
on_events_start
--
do
z_acceleration_proportion := 0.5
reset
end
radians_per_millisec: DOUBLE
--
do
Result := 2 * PI / millisecs_per_cycle
end
Background_tile: EV_PIXMAP
--
once
Result := Image.pixmap ("floral.png")
end
Soccer_ball_image: EV_PIXMAP
--
once
Result := Image.pixmap ("soccer-ball.png")
end
millisecs_per_cycle: DOUBLE
z_acceleration_proportion: DOUBLE
x_pos, y_pos, radius: INTEGER
proportion_z: DOUBLE
tiles: ARRAY [EV_MODEL_PICTURE]
is_electron_behind_proton: BOOLEAN
feature {NONE} -- Constants
Stock_colors: EV_STOCK_COLORS
--
once
create Result
end
Frames_per_sec: INTEGER
do
Result := Args.value ("frames").to_integer
end
Colors: EV_STOCK_COLORS
--
once
create Result
end
Count_label: ZSTRING
once
Result := "Redraws"
end
end