-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.pony
151 lines (124 loc) · 3.6 KB
/
main.pony
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
use "buffered"
use "collections"
use "files"
use "random"
use "time"
class val ReadFileError
let _message: String
new val create(message: String) =>
_message = message
fun string(): String iso^ =>
_message.clone()
primitive ReadFile
fun apply(file_name: String, auth: AmbientAuth): (Array[U8] val | ReadFileError) =>
let path = try
FilePath(auth, file_name)?
else
return ReadFileError("Could not open '" + file_name + "'")
end
match OpenFile(path)
| let file: File =>
file.read(file.size())
else
ReadFileError("Error reading '" + file_name + "'")
end
primitive WithPolarLines
fun apply(intensity: Array[Array[F64]], pol_x: F64, pol_y: F64, a_start: F64, a_end: F64, a_step: F64, cutoff: F64, os: OutStream): PathCommands =>
let lines = PathCommands
try
let w = intensity.size()
let h = intensity(0)?.size()
for a in Range[F64](a_start, a_end + (a_step / 10), a_step) do
let x_dim = a.cos()
let y_dim = a.sin()
let max_dim = x_dim.abs().max(y_dim.abs())
let step_size_w = x_dim / max_dim
let step_size_h = y_dim / max_dim
var cur_x: F64 = pol_x
var cur_y: F64 = pol_y
var start_x: F64 = pol_x
var start_y: F64 = pol_y
var last_x: F64 = pol_x
var last_y: F64 = pol_y
var s: F64 = 0
var drawing = false
while (cur_x >= 0) and (cur_x < w.f64()) and (cur_y >= 0) and (cur_y < h.f64()) do
if drawing then
try
if intensity(cur_x.usize())?(cur_y.usize())? > cutoff then
if (start_x != last_x) and (start_y != last_y) then
lines
.>command(PathMove.abs(start_x, start_y))
.>command(PathLine.abs(last_x, last_y))
end
drawing = false
else
last_x = cur_x
last_y = cur_y
end
else
os.print("ERROR")
error
end
else
try
if intensity(cur_x.usize())?(cur_y.usize())? <= cutoff then
start_x = cur_x
start_y = cur_y
last_x = cur_y
last_y = cur_y
drawing = true
end
else
os.print("ERROR")
error
end
end
cur_x = cur_x + step_size_w
cur_y = cur_y + step_size_h
end
end
end
lines
actor Main
new create(env: Env) =>
let file_name = try
env.args(1)?
else
env.err.print("first argument must be a file name")
return
end
let auth = try
env.root as AmbientAuth
else
env.err.print("Could not get ambient authority")
return
end
let bmp_data = match ReadFile(file_name, auth)
| let data: Array[U8] val =>
data
| let e: ReadFileError =>
env.err.print(e.string())
return
end
let bm = try
Bitmap.read_from(bmp_data)?
else
env.err.print("Error reading bitmap file")
return
end
let intensity = bm.intensity()
let svg = SVG.svg()
let w = intensity.size().f64()
let h = try intensity(0)?.size().f64() else 0 end
let a_step: F64 = 0.03
let pcs = PathCommands
for pl in [
WithPolarLines(intensity, 0, h / 2, 0, F64.pi() * 2, a_step, 0.3, env.err)
WithPolarLines(intensity, w - 1, h / 2, 0, F64.pi() * 2, a_step, 0.3, env.err)
WithPolarLines(intensity, w / 2, h / 2, 0, F64.pi() * 2, a_step, 0.5, env.err)
].values() do
pcs.commands(pl)
end
svg.c(SVG.path(pcs))
env.out.print(svg.render())