forked from LingDong-/wax
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathline.wax
155 lines (139 loc) · 3.09 KB
/
line.wax
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
152
153
154
155
;; line.wax
;; rasterize lines using simple line algorithm
(@include math)
;; datastructure for storing an image
(struct image
(let data (arr int))
(let w int) ; width
(let h int) ; height
)
;; initialize an image full of zeros
(func zeros (param w int) (param h int)
(result (struct image))
(let data (arr int) (alloc (arr int)))
(let im (struct image) (alloc (struct image)))
(for i 0 (< i (* w h)) 1 (do
(insert data (# data) 0)
))
(set im data data)
(set im w w)
(set im h h)
(return im)
)
;; read value of a pixel
(func getpixel
(param im (struct image))
(param x int) (param y int)
(result int)
(if (|| ; boundary check
(< x 0) (< y 0)
(>= x (get im w))
(>= y (get im h))
)(then
(return 0)
))
(return
(get im data (+ (* y (get im w)) x))
)
)
;; write value to a pixel
(func setpixel
(param im (struct image))
(param x int) (param y int) (param v int)
(if (|| ; boundary check
(< x 0) (< y 0)
(>= x (get im w))
(>= y (get im h))
)(then
(return)
))
(set (get im data)
(+ (* y (get im w)) x)
v
)
)
;; helper for line drawing algorithm
;; compute x/y from y/x using slope
(func linestep
(param sx0 int) (param sx1 int)
(param sy0 int) (param sy1 int)
(param x int)
(result int)
(if (= sx0 sx1) (then
(return sy1)
))
(return (cast (call round
(+ sy0 (*
(- x sx0)
(/ (- sy1 sy0) (cast (- sx1 sx0) float) )
))
) int))
)
;; raster line drawing algorithm
(func line
(param im (struct image))
(param x0 float) (param y0 float) ; start pos
(param x1 float) (param y1 float) ; end pos
(param v int) ;color
(let sx0 int (call round x0))
(let sy0 int (call round y0))
(let sx1 int (call round x1))
(let sy1 int (call round y1))
(let dx int (? (> sx1 sx0) 1 -1)) ; x increment
(let dy int (? (> sy1 sy0) 1 -1)) ; y increment
(if (>=
(call abs (- sx0 sx1))
(call abs (- sy0 sy1))
)(then ; slope < 1 ?
(let x int sx0)
(while (<> x (+ sx1 dx)) (do
(let y int (call linestep sx0 sx1 sy0 sy1 x))
(call setpixel im x y v)
(set x (+ x dx))
))
)(else
(let y int sy0)
(while (<> y (+ sy1 dy)) (do
(let x int (call linestep sy0 sy1 sx0 sx1 y))
(call setpixel im x y v)
(set y (+ y dy))
))
))
)
;; visualize the image with ASCII drawing in terminal
(func imshow (param im (struct image))
(local s str (alloc str "+"))
(for j 0 (< j (get im w)) 1 (do (<< s "-")))
(<< s "+\n")
(for i 0 (< i (get im h)) 1 (do
(<< s "|")
(for j 0 (< j (get im w)) 1 (do
(<< s (+ (call getpixel im j i) 32))
))
(<< s "|\n")
))
(<< s "+")
(for j 0 (< j (get im w)) 1 (do (<< s "-")))
(<< s "+")
(print s)
)
;; free allocated image
(func dispose (param im (struct image))
(free (get im data))
(free im)
)
(func main (result int)
(let im (struct image) (call zeros 60 30))
;; generate some random lines to draw
(for i 0 (< i 7) 1 (do
(let x0 float (* (call random) (get im w)))
(let y0 float (* (call random) (get im h)))
(let x1 float (* (call random) (get im w)))
(let y1 float (* (call random) (get im h)))
(let v int (+ i 1))
(call line im x0 y0 x1 y1 v)
))
(call imshow im)
(call dispose im)
(return 0)
)