indexing description: "[ An object representing an axis-aligned boxed subspace of R3. ]" author: "" date: "$Date$" revision: "$Revision$" class EM_INTERVAL_3D_REF create make_from_tuple, make_from_reference, make_from_intervals, make, default_create convert make_from_tuple ({TUPLE [EM_INTERVAL, EM_INTERVAL, EM_INTERVAL]}) feature -- Initialization make_from_tuple (t: TUPLE [x, y, z: EM_INTERVAL]) is -- Make 3D interval from tuple do x := t.x y := t.y z := t.z ensure set: x = t.x and y = t.y and z = t.z end make_from_reference (other: like Current) is -- do x := other.x y := other.y z := other.z ensure set: x = other.x and y = other.y and z = other.z end make (p1, p2: like min) is -- Set boundary to be hull of values `p1' and 'p2' do x.set (p1.x, p2.x) y.set (p1.y, p2.y) z.set (p1.z, p2.z) ensure -- set: containment: contains_value (p1) and contains_value (p2) end make_from_intervals (x_interval: like x; y_interval: like y; z_interval: like z) -- Set interval for each axis directly. do x := x_interval y := y_interval z := z_interval ensure set: x_interval = x and y_interval = y and z_interval = z end feature -- Access x: EM_INTERVAL -- Projection of subspace onto x-axis y: EM_INTERVAL -- Projection of subspace onto y-axis z: EM_INTERVAL -- Projection of subspace onto z-axis feature -- Measurement min: EM_VECTOR3D is -- Lower boundary for each axis do Result.set (x.min, y.min, z.min) ensure definition: Result = [x.min, y.min, z.min] end max: like min is -- Upper boundary for each axis do Result.set (x.max, y.max, z.max) ensure definition: Result = [x.max, y.max, z.max] end size: like min is -- Size for each axis do Result := max - min ensure definition: Result = max - min end center: like min is -- Midpoint between `min' and `max' do Result.set (x.center, y.center, z.center) ensure definition: Result = [x.center, y.center, z.center] end width: DOUBLE is -- Size of `x' interval do Result := x.size ensure definition: Result = x.size end height: DOUBLE is -- Size of `y' interval do Result := y.size ensure definition: Result = y.size end depth: DOUBLE is -- Size of `z' interval do Result := z.size ensure definition: Result = z.size end feature -- Element change set_x (interval: like x) is -- Set `x' interval directly do x := interval ensure set: x = interval end set_y (interval: like y) is -- Set `y' interval directly do y := interval ensure set: y = interval end set_z (interval: like z) is -- Set `z' interval directly do z := interval ensure set: z = interval end set_min (value: like min) is -- Set lower boundary for each axis require constraint: value.x <= max.x and value.y <= max.y and value.z <= max.z do x.set_min (value.x) y.set_min (value.y) z.set_min (value.z) ensure set: min = value end set_max (value: like max) is -- Set upper boundary for each axis require constraint: value.x >= min.x and value.y >= min.y and value.z >= min.z do x.set_max (value.x) y.set_max (value.y) z.set_max (value.z) ensure set: max = value end feature -- Basic queries contains_value (value: like min): BOOLEAN is -- Is `value' contained within current interval? do Result := x.contains_value (value.x) and y.contains_value (value.y) and z.contains_value (value.z) ensure end fully_contains (other: like Current): BOOLEAN is -- Is `other' interval fully contained within current interval? do Result := contains_value (other.min) and contains_value (other.max) ensure end intersects, partially_contains (other: like Current): BOOLEAN is -- Does `other' interval intersect with current? do Result := x.intersects_interval (other.x) and y.intersects_interval (other.y) and z.intersects_interval (other.z) ensure end feature -- Basic operations align_value (value: like min; alignment: EM_ALIGNMENT_3D): like min is -- Aligned `value' with `other' interval according to alignment do Result.set ( x.align_value (value.x, alignment.x), y.align_value (value.y, alignment.y), z.align_value (value.z, alignment.z) ) end clamp_value (value: like min): like min is -- Return element of interval with shortest distance to `value' do Result.set ( x.clamp_value (value.x), y.clamp_value (value.y), z.clamp_value (value.z) ) ensure contains_result: contains_value (Result) end feature -- Transformation accommodate_value (value: like min) is -- Expand current interval by as much as needed to accomodate -- `value'. No shrinking is allowed do x.accommodate_value (value.x) y.accommodate_value (value.y) z.accommodate_value (value.z) ensure containment: contains_value (value) end accommodate (other: like Current) is -- Expand current interval by as much as needed to accomodate -- `other' interval. No shrinking is allowed do accommodate_value (other.min) accommodate_value (other.max) ensure containment: fully_contains (other) end align_with (other: like Current; alignment: EM_ALIGNMENT_3D) is -- Align current interval with `other' interval according to -- `alignment' do x.align_with (other.x, alignment.x) y.align_with (other.y, alignment.y) z.align_with (other.z, alignment.z) ensure -- aligned_with_other: ... end align_with_value (value: like min; alignment: EM_ALIGNMENT_3D) is -- Align current interval with `value' according to `alignment' do x.align_with_value (value.x, alignment.x) y.align_with_value (value.y, alignment.y) z.align_with_value (value.z, alignment.z) ensure -- aligned_with_value: ... end clamp_with (other: like Current) is -- Clamp boundaries of current interval to fit within `other' -- interval. May result in empty interval with size = 0 if -- `current' lies completely outside `other' interval. do x.clamp_with (other.x) y.clamp_with (other.y) z.clamp_with (other.z) ensure containment: other.fully_contains (Current) end resize (new_size: like size) -- Set `size' to absolute value of `new_size' do x.resize (new_size.x) y.resize (new_size.y) z.resize (new_size.z) end pad (a_padding: like size) is -- Add `a_padding' to both sides of interval by adjusting -- both `min' and `max' such that `size' will always be positive do x.pad (a_padding.x) y.pad (a_padding.y) z.pad (a_padding.z) end aligned_resize (new_size: like size; alignment: EM_ALIGNMENT_3D) -- Resize current interval to `new_size', and align result with -- old boundaries according to `alignment'. -- If `alignment'.is_user_specified, this operation is equal -- to a normal resize do x.aligned_resize (new_size.x, alignment.x) y.aligned_resize (new_size.y, alignment.y) z.aligned_resize (new_size.z, alignment.z) end translate (distance: like min) -- Translate current interval by `distance' do x.translate (distance.x) y.translate (distance.y) z.translate (distance.z) ensure -- same_size: old size = size -- definition: min = old min + distance and max = old max + distance end invariant -- already covered by EM_INTERVAL for x, y, and z end