Skip to content

Commit abb61d1

Browse files
committed
Make triangles able to raster images
1 parent 9c06e2f commit abb61d1

12 files changed

+213
-79
lines changed

app/lib/dinraal.rb

+74-30
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,15 @@ def circle_outline(options = {})
4444

4545
angle = 0
4646
while angle < 360
47-
new_pixel = point_at_distance_angle(point: { x: x, y: y }, distance: radius, angle: angle)
47+
new_pixel = point_at_distance_angle(point: { x: x, y: y },
48+
distance: radius,
49+
angle: angle)
4850

4951
new_pixel[:x] = new_pixel[:x].floor
5052
new_pixel[:y] = new_pixel[:y].floor
5153

52-
possible_pixel = { x: new_pixel[:x], y: new_pixel[:y], w: 1, h: 1, r: r, g: g, b: b, a: a }.solid!
54+
possible_pixel = { x: new_pixel[:x], y: new_pixel[:y], w: 1, h: 1,
55+
r: r, g: g, b: b, a: a }.solid!
5356

5457
pixels << possible_pixel unless pixels.include?(possible_pixel)
5558
angle += 1
@@ -82,7 +85,8 @@ def circle_raster(options = {})
8285
pixels[x_min] ||= []
8386
y_min = y - radius
8487
while y_min <= y_max
85-
possible_pixel = { x: x_min, y: y_min, w: 1, h: 1, r: r, g: g, b: b, a: a }.solid!
88+
possible_pixel = { x: x_min, y: y_min, w: 1, h: 1,
89+
r: r, g: g, b: b, a: a }.solid!
8690
pixels[x_min][y_min] = possible_pixel if args.geometry.point_inside_circle?({ x: x_min, y: y_min }, { x: x, y: y }, radius)
8791
y_min += 1
8892
end
@@ -108,19 +112,19 @@ def point_inside_triangle?(point:, triangle:)
108112
triangle = triangle.reverse
109113

110114
leg0 = [triangle[0], triangle[1]]
111-
leg0_slope = args.geometry.line_slope(leg0.flatten)
115+
leg0_slope = args.geometry.line_slope(leg0.flatten, replace_infinity: 1080)
112116
leg0_intercept = triangle[0][1] - (leg0_slope * triangle[0][0])
113117

114118
return false unless point_y <= leg0_slope * point_x + leg0_intercept
115119

116120
leg1 = [triangle[0], triangle[2]]
117-
leg1_slope = args.geometry.line_slope(leg1.flatten)
121+
leg1_slope = args.geometry.line_slope(leg1.flatten, replace_infinity: 1080)
118122
leg1_intercept = triangle[0][1] - (leg1_slope * triangle[0][0])
119123

120124
return false unless point_y <= leg1_slope * point_x + leg1_intercept
121125

122126
leg2 = [triangle[1], triangle[2]]
123-
leg2_slope = args.geometry.line_slope(leg2.flatten)
127+
leg2_slope = args.geometry.line_slope(leg2.flatten, replace_infinity: 1080)
124128
leg2_intercept = triangle[2][1] - (leg2_slope * triangle[2][0])
125129

126130
return false unless point_y >= leg2_slope * point_x + leg2_intercept
@@ -166,61 +170,101 @@ def triangle_raster(options = {})
166170
y2 = options[:y2]
167171
x3 = options[:x3]
168172
y3 = options[:y3]
169-
r = options[:r]
170-
g = options[:g]
171-
b = options[:b]
172-
a = options[:a]
173+
174+
r = options[:r].nil? ? 0 : options[:r]
175+
g = options[:g].nil? ? 0 : options[:g]
176+
b = options[:b].nil? ? 0 : options[:b]
177+
a = options[:a].nil? ? 255 : options[:a]
178+
179+
path = options[:path].nil? ? 'pixel' : options[:path]
180+
181+
image_width = options[:image_width].nil? ? [x, x2, x3].max - [x, x2, x3].min : options[:image_width]
173182

174183
args = $gtk.args
175184
triangle = [[x, y], [x2, y2], [x3, y3]]
176185
triangle = triangle.sort_by { |point| point[1] }
177186
triangle = triangle.reverse
178187

179-
line_slope = args.geometry.line_slope [triangle[0][0], triangle[0][1], triangle[2][0], triangle[2][1]]
188+
line_slope = args.geometry.line_slope([triangle[0][0], triangle[0][1], triangle[2][0], triangle[2][1]], replace_infinity: 1080)
180189
x_intercept = triangle[0][1] - (line_slope * triangle[0][0])
181190

182191
vertex4 = [(triangle[1][1] - x_intercept) / line_slope, triangle[1][1]]
183192

184193
leg0 = [triangle[0], triangle[1]]
185-
leg0_slope = args.geometry.line_slope(leg0.flatten)
194+
leg0_slope = args.geometry.line_slope(leg0.flatten, replace_infinity: 1080)
186195
leg0_intercept = triangle[0][1] - (leg0_slope * triangle[0][0])
187196

188197
leg1 = [triangle[0], vertex4]
189-
leg1_slope = args.geometry.line_slope(leg1.flatten)
198+
leg1_slope = args.geometry.line_slope(leg1.flatten, replace_infinity: 1080)
190199
leg1_intercept = triangle[0][1] - (leg1_slope * triangle[0][0])
191200

192-
leg2 = [triangle[2], triangle[1]]
193-
leg2_slope = args.geometry.line_slope(leg2.flatten)
201+
leg2 = [triangle[1], triangle[2]]
202+
leg2_slope = args.geometry.line_slope(leg2.flatten, replace_infinity: 1080)
194203
leg2_intercept = triangle[2][1] - (leg2_slope * triangle[2][0])
195204

196-
leg3 = [triangle[2], vertex4]
197-
leg3_slope = args.geometry.line_slope(leg3.flatten)
205+
leg3 = [vertex4, triangle[2]]
206+
leg3_slope = args.geometry.line_slope(leg3.flatten, replace_infinity: 1080)
198207
leg3_intercept = triangle[2][1] - (leg3_slope * triangle[2][0])
199208

200209
raster_lines = []
201210

211+
x_offset = [x, x2, x3].min
212+
y_offset = [y, y2, y3].min
213+
202214
y_iter = triangle[0][1]
203215
while y_iter >= vertex4[1]
216+
start_x = (y_iter - leg0_intercept) / leg0_slope
217+
end_x = (y_iter - leg1_intercept) / leg1_slope
218+
219+
sort_list = [start_x, end_x].sort
220+
small_x = sort_list[0]
221+
big_x = sort_list[1]
222+
223+
start_x = small_x
224+
end_x = big_x
225+
226+
draw_width = end_x - x_offset > image_width ? image_width - start_x + x_offset : end_x - start_x
227+
228+
grab = draw_width.abs
204229
raster_lines << {
205-
x: (y_iter - leg0_intercept) / leg0_slope,
230+
x: start_x,
206231
y: y_iter,
207-
x2: (y_iter - leg1_intercept) / leg1_slope,
208-
y2: y_iter,
209-
r: r, g: g, b: b, a: a
210-
}.line!
232+
w: draw_width,
233+
h: 1,
234+
r: r, g: g, b: b, a: a,
235+
path: path,
236+
source_x: start_x - x_offset, source_y: y_iter - y_offset,
237+
source_w: grab, source_h: 1
238+
}.sprite!
211239
y_iter -= 1
212240
end
213241

214-
y_iter = triangle[2][1]
215-
while y_iter <= vertex4[1]
242+
y_iter = vertex4[1]
243+
while y_iter >= triangle[2][1]
244+
start_x = (y_iter - leg2_intercept) / leg2_slope
245+
end_x = (y_iter - leg3_intercept) / leg3_slope
246+
247+
sort_list = [start_x, end_x].sort
248+
small_x = sort_list[0]
249+
big_x = sort_list[1]
250+
251+
start_x = small_x
252+
end_x = big_x
253+
254+
draw_width = end_x - x_offset > image_width ? image_width - start_x + x_offset : end_x - start_x
255+
256+
grab = draw_width.abs
216257
raster_lines << {
217-
x: (y_iter - leg2_intercept) / leg2_slope,
258+
x: start_x,
218259
y: y_iter,
219-
x2: (y_iter - leg3_intercept) / leg3_slope,
220-
y2: y_iter,
221-
r: r, g: g, b: b, a: a
222-
}.line!
223-
y_iter += 1
260+
w: draw_width,
261+
h: 1,
262+
r: r, g: g, b: b, a: a,
263+
path: path,
264+
source_x: start_x - x_offset, source_y: y_iter - y_offset,
265+
source_w: grab, source_h: 1
266+
}.sprite
267+
y_iter -= 1
224268
end
225269
raster_lines
226270
end

app/main.rb

+32-19
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,52 @@
1+
$gtk.reset
2+
13
require 'app/lib/dinraal.rb'
24

3-
$gtk.reset
5+
def make_rt(args)
6+
args.render_target(:static_rt).clear_before_render = true
7+
args.render_target(:static_rt).primitives << Dinraal.triangle_raster(args.state.tri1)
48

5-
def tick(args)
6-
tri1 = { x: 100, y: 100, x2: 250, y2: 600, x3: 900, y3: 500, r: 255 }
7-
tri2 = { x: 130, y: 130, x2: 200, y2: 300, x3: 400, y3: 400, b: 255 }
9+
args.render_target(:static_rt).primitives << Dinraal.circle_outline(x: 20, y: 580, radius: 20, g: 255)
10+
args.render_target(:static_rt).primitives << Dinraal.circle_raster(x: 70, y: 580, radius: 20, b: 255)
811

9-
if args.state.tick_count.zero?
10-
args.render_target(:static_rt).clear_before_render = true
12+
args.render_target(:static_rt).primitives << Dinraal.triangle_outline(args.state.tri1)
13+
args.render_target(:static_rt).primitives << Dinraal.triangle_outline(args.state.tri2)
14+
15+
args.render_target(:static_rt).primitives << Dinraal.triangle_center(args.state.tri1).merge(w: 5, h: 5, g: 255).solid!
16+
args.render_target(:static_rt).primitives << Dinraal.triangle_center(args.state.tri2).merge(w: 5, h: 5, g: 255).solid!
1117

12-
args.render_target(:static_rt).primitives << Dinraal.triangle_raster(tri1)
18+
args.render_target(:static_rt).primitives << Dinraal.triangle_bounding_box(args.state.tri1)
19+
args.render_target(:static_rt).primitives << Dinraal.triangle_bounding_box(args.state.tri2)
20+
end
21+
22+
def tick(args)
23+
# args.state.tri1 ||= { x: 800, y: 500, x2: 450, y2: 650, x3: 400, y3: 300, path: 'sprites/rick.png', image_width: 300 }
24+
args.state.tri1 ||= { x: 800, y: 500, x2: 450, y2: 650, x3: 400, y3: 300, g: 255 }
25+
args.state.tri2 ||= { x: 200, y: 600, x2: 400, y2: 600, x3: 275, y3: 500, r: 255 }
1326

14-
args.render_target(:static_rt).primitives << Dinraal.circle_outline(x: 500, y: 500, radius: 20, g: 255)
27+
new_tri = args.state.tri1.merge(x: args.inputs.mouse.x, y: args.inputs.mouse.y)
1528

16-
args.render_target(:static_rt).primitives << Dinraal.circle_raster(x: 700, y: 500, radius: 20, b: 255)
29+
if args.state.tick_count.zero?
30+
make_rt(args)
31+
elsif args.inputs.mouse.up && new_tri != args.state.tri1
32+
args.state.tri1 = new_tri
33+
make_rt(args)
34+
else
35+
args.render_target(:static_rt).clear_before_render = false
1736
end
1837

1938
outputs = []
2039
outputs << { x: 0, y: 0, w: 1280, h: 720, path: :static_rt }.sprite!
2140

22-
outputs << Dinraal.triangle_outline(tri2)
23-
outputs << Dinraal.triangle_center(tri1).merge(w: 5, h: 5, g: 255).solid!
24-
outputs << Dinraal.triangle_center(tri2).merge(w: 5, h: 5, g: 255).solid!
25-
2641
mouse_x = args.inputs.mouse.x
2742
mouse_y = args.inputs.mouse.y
2843

29-
mouse_inside = Dinraal.point_inside_triangle?(point: { x: mouse_x, y: mouse_y }, triangle: tri1)
30-
31-
outputs << { x: args.grid.center_x, y: 720, text: "Mouse inside red: #{mouse_inside}", alignment_enum: 1 }.label!
44+
mouse_inside = Dinraal.point_inside_triangle?(point: { x: mouse_x, y: mouse_y }, triangle: args.state.tri1)
3245

33-
outputs << Dinraal.triangle_bounding_box(tri2)
46+
outputs << { x: args.grid.center_x, y: 720, text: "Mouse inside image: #{mouse_inside}", alignment_enum: 1 }.label!
3447

35-
two_contains_one = Dinraal.triangle_inside_triangle?(inner: tri2, outer: tri1)
36-
outputs << { x: args.grid.center_x, y: 700, text: "Red triangle contains blue triangle: #{two_contains_one}", alignment_enum: 1 }.label!
48+
two_contains_one = Dinraal.triangle_inside_triangle?(inner: args.state.tri2, outer: args.state.tri1)
49+
outputs << { x: args.grid.center_x, y: 700, text: "Image contains red triangle: #{two_contains_one}", alignment_enum: 1 }.label!
3750

3851
args.outputs.primitives << outputs
3952

exceptions/current.txt

+5-14
Large diffs are not rendered by default.

exceptions/game_state_0.txt

+3-3
Large diffs are not rendered by default.

exceptions/game_state_1.txt

+6-13
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)