19928/jj_vitp/jj_override/ev_model_elliptic.e

304 lines
6.5 KiB
Plaintext
Raw Permalink Normal View History

2024-06-17 07:09:33 +00:00
note
description: "[
An EV_FIGURE_ELLIPTIC is defined by pa and pb
and not rotatable. If you need a rotatable elliptic
use a EV_FIGURE_ROTATED_ELLIPTIC but if not elliptic
is a lot faster.
pa-----------
| |
| |
| center |
| |
| |
----------- pb
radius1 is half horizontal distance between pa and pb.
radius2 is half vertical distance between pa and pb.
]"
legal: "See notice at end of class."
status: "See notice at end of class."
date: "$Date: 2013-04-25 18:08:32 -0400 (Thu, 25 Apr 2013) $"
revision: "$Revision: 33 $"
deferred class
EV_MODEL_ELLIPTIC
inherit
EV_MODEL_ATOMIC
export
{ANY} Pi
undefine
point_count
redefine
default_create,
bounding_box
end
EV_MODEL_DOUBLE_POINTED
undefine
default_create
end
feature {NONE} -- Initialization
default_create
-- Create a EV_FIGURE_ELLIPTIC at (0,0) with no dimension.
do
Precursor {EV_MODEL_ATOMIC}
create point_array.make_empty (2)
point_array.extend (create {EV_COORDINATE}.make (0, 0))
point_array.extend (create {EV_COORDINATE}.make (0, 0))
is_center_valid := True
end
feature -- Access
angle: DOUBLE = 0.0
-- Since not rotatable.
is_scalable: BOOLEAN
-- Elliptic is scalable.
do
Result := True
end
is_rotatable: BOOLEAN
-- Elliptic is not rotatable.
-- (Use a rotatable_elliptic)
do
-- jjj Result := False
Result := True
end
is_transformable: BOOLEAN
-- Elliptic is not transformable.
do
-- jjj Result := False
Result := True
end
radius1: INTEGER
-- The horizontal radius.
local
l_point_array: like point_array
p0, p1: EV_COORDINATE
do
l_point_array := point_array
p0 := l_point_array.item (0)
p1 := l_point_array.item (1)
Result := as_integer ((p0.x_precise - p1.x_precise) / 2).abs
end
radius2: INTEGER
-- The vertical radius.
local
l_point_array: like point_array
p0, p1: EV_COORDINATE
do
l_point_array := point_array
p0 := l_point_array.item (0)
p1 := l_point_array.item (1)
Result := as_integer ((p0.y_precise - p1.y_precise) / 2).abs
end
point_a_x: INTEGER
-- x position of `point_b'.
do
Result := point_array.item (0).x
end
point_a_y: INTEGER
-- y position of `point_b'.
do
Result := point_array.item (0).y
end
point_b_x: INTEGER
-- x position of `point_b'.
do
Result := point_array.item (1).x
end
point_b_y: INTEGER
-- y position of `point_b'.
do
Result := point_array.item (1).y
end
feature -- Element change
set_radius1 (radius: INTEGER)
-- Set `radius1' to `radius'.
require
radius_positive: radius >= 0
local
l_point_array: like point_array
p0, p1: EV_COORDINATE
cx: DOUBLE
do
l_point_array := point_array
p0 := l_point_array.item (0)
p1 := l_point_array.item (1)
cx := (p0.x_precise + p1.x_precise) / 2
p0.set_x_precise (cx - radius)
p1.set_x_precise (cx + radius)
invalidate
center_invalidate
ensure
set: radius1 = radius
end
set_radius2 (radius: INTEGER)
-- Set `radius2' to `radius'.
require
radius_positive: radius >= 0
local
l_point_array: like point_array
p0, p1: EV_COORDINATE
cy: DOUBLE
do
l_point_array := point_array
p0 := l_point_array.item (0)
p1 := l_point_array.item (1)
cy := (p0.y_precise + p1.y_precise) / 2
p0.set_y_precise (cy - radius)
p1.set_y_precise (cy + radius)
invalidate
center_invalidate
ensure
set: radius2 = radius
end
set_radius1_and_radius2 (a_radius1, a_radius2: INTEGER)
-- Set `radius1' to `a_radius1' and `radius2` to `a_radius2'.
require
radius1_positive: a_radius1 >= 0
radius2_positive: a_radius2 >= 0
local
l_point_array: like point_array
p0, p1: EV_COORDINATE
cx, cy: DOUBLE
do
l_point_array := point_array
p0 := l_point_array.item (0)
p1 := l_point_array.item (1)
cx := (p0.x_precise + p1.x_precise) / 2
cy := (p0.y_precise + p1.y_precise) / 2
p0.set_x_precise (cx - a_radius1)
p1.set_x_precise (cx + a_radius1)
p0.set_y_precise (cy - a_radius2)
p1.set_y_precise (cy + a_radius2)
invalidate
center_invalidate
ensure
set: radius1 = a_radius1 and radius2 = a_radius2
end
set_point_a_position (ax, ay: INTEGER)
-- Set position of `point_a' to position of (`ax', `ay').
do
point_array.item (0).set_precise (ax, ay)
invalidate
center_invalidate
end
set_point_b_position (ax, ay: INTEGER)
-- Set position of `point_b' to position of (`ax', `ay').
do
point_array.item (1).set_precise (ax, ay)
invalidate
center_invalidate
end
feature -- Events
bounding_box: EV_RECTANGLE
-- Smallest orthegonal rectangle `Current' fits in.
local
min_x, min_y, max_x, max_y, lw2, v1, v2: DOUBLE
lx, ly, w, h: INTEGER
l_point_array: like point_array
pa, pb: EV_COORDINATE
do
if attached internal_bounding_box as l_internal_bounding_box and then l_internal_bounding_box.has_area then
Result := l_internal_bounding_box.twin
else
l_point_array := point_array
pa := l_point_array.item (0)
pb := l_point_array.item (1)
v1 := pa.x_precise
v2 := pb.x_precise
min_x := v1.min (v2)
max_x := v1.max (v2)
v1 := pa.y_precise
v2 := pb.y_precise
min_y := v1.min (v2)
max_y := v1.max (v2)
check
max_x >= min_x
max_y >= min_y
end
lw2 := line_width / 2
lx := as_integer (min_x - lw2)
ly := as_integer (min_y - lw2)
w := as_integer ((max_x - min_x) + lw2) + 1
h := as_integer ((max_y - min_y) + lw2) + 1
create Result.make (lx, ly, w, h)
if attached internal_bounding_box as l_internal_bounding_box then
l_internal_bounding_box.copy (Result)
else
internal_bounding_box := Result.twin
end
end
end
feature {NONE} -- Implementation
set_center
-- Set position of the center.
local
l_point_array: like point_array
pa, pb: EV_COORDINATE
do
l_point_array := point_array
pa := l_point_array.item (0)
pb := l_point_array.item (1)
center.set_precise ((pa.x_precise + pb.x_precise) / 2, (pa.y_precise + pb.y_precise) / 2)
is_center_valid := True
end
note
copyright: "Copyright (c) 1984-2006, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
356 Storke Road, Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end -- class EV_MODEL_ELLIPTIC