1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
class CALIBRATION
-- This class is able to
-- - build some calibration grid with user assistance,
-- - save calibration grid,
-- - reload calibration grid,
-- - use calibration grid for coordinates conversion.
create {ANY}
make
feature {}
make is
do
create reference_points.make
end
feature {ANY}
ready: BOOLEAN
build (display_width_, display_height_: INTEGER) is
local
uncalibrated: FAST_ARRAY[INTEGER]
do
display_width := display_width_
display_height := display_height_
from
uncalibrated := {FAST_ARRAY[INTEGER] <<0, 0, display_width, display_height>>}
until
uncalibrated.is_empty
loop
end
ensure
ready
end
write_to (os: OUTPUT_STREAM) is
require
os.is_connected
do
ensure
os.is_connected
end
load_from (data: INPUT_STREAM) is
require
data.is_connected
do
end
set_offset(x_display, y_display: INTEGER) is
do
x_offset := x_display
y_offset := y_display
end
convert (x_device, y_device: INTEGER) is
-- Result is available in last_x, last_y
require
x_device.in_range(0, device_width)
y_device.in_range(0, device_height)
local
i, j: INTEGER
x_rest, y_rest: INTEGER
do
i := x_device // horizontal_step
j := y_device // vertical_step
x_rest := x_device - i * horizontal_step
y_rest := y_device - j * vertical_step
if y_rest * 2 < vertical_step then
last_x := ((x_table.item(i, j) * x_rest + x_table.item(i + 1, j) * (horizontal_step - x_rest)) / horizontal_step).force_to_integer_32
else
last_x := ((x_table.item(i, j + 1) * x_rest + x_table.item(i + 1, j + 1) * (horizontal_step - x_rest)) / horizontal_step).force_to_integer_32
end
if x_rest * 2 < horizontal_step then
last_y := ((y_table.item(i, j) * y_rest + y_table.item(i, j + 1) * (vertical_step - y_rest)) / vertical_step).force_to_integer_32
else
last_y := ((y_table.item(i + 1, j) * y_rest + y_table.item(i + 1, j + 1) * (vertical_step - y_rest)) / vertical_step).force_to_integer_32
end
ensure
last_x.in_range(x_offset, x_offset + display_width -1)
last_y.in_range(y_offset, y_offset + display_height - 1)
end
last_x, last_y: INTEGER
-- Last conversion result (in display coordinates)
feature {}
x_offset, y_offset, display_width, display_height: INTEGER
-- coordinates and size of the displayed area in pixels
x_table, y_table: FAST_ARRAY2[REAL]
-- Store display coordinates for device coordinate. Use
-- `horizontal_step' and `vertical_step' for table indexes values.
horizontal_step, vertical_step: INTEGER
-- Indexes steps for tables
device_width, device_height: INTEGER
-- Digitizer size
reference_points: REFERENCE_POINTS
-- 4 values per reference point x_device
end
|