pixelflow_canvas 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 16988e8bddedf30d6888b7b10cf043c083bc160a4eb6de56e464a2305f4455d3
4
- data.tar.gz: 3b5d6c3ce3fb0cd5ac830e2fd176f8ea79b4c02bc9326e14680f5efc19c370c6
3
+ metadata.gz: 4824696c6996cc136b56dd83a716fa12a273e0682744473b67f0ffb7693b7335
4
+ data.tar.gz: 612927ef865f29432b41adbaa11b0d4b6e824a9af15cd75413c7e5c7fa0c84b1
5
5
  SHA512:
6
- metadata.gz: 5440dd62074ba1dbf5f0cb31262448b8bd7e1a2c666717f82af3d7ddcfea8eb25537505f76ae3cb3252984799f3bef87142ced690500d41fbd3e36b54ac5369a
7
- data.tar.gz: d5b667dcf19fe88d8a8279f7a4ef9bd4d9411cff7b9b0eff85537c387e3bde622d2e586ce2e73dd10627ca6d40866c6e19f28c537a691a7d60434b682771f087
6
+ metadata.gz: ed40b86854a8779791ca67eb41d0b881ea76e917e72305e391f693cdbfaa6157f2e34402038c300f30b1b7d67414c4722ba3808caf5abd50ea76149fe3915016
7
+ data.tar.gz: e0311899a97ba6959dc457f1dbb1397c8495a730e99c813e5b5809875e9127344410856d4bfc3e2afed6b504492693aeffedf62b4f1937702edc6a49f4d11af7
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PixelflowCanvas
4
- VERSION = "0.3.0"
4
+ VERSION = "0.4.1"
5
5
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative "pixelflow_canvas/version"
4
4
  require 'socket'
5
+ require 'time'
5
6
 
6
7
  module Pixelflow
7
8
  class Canvas
@@ -29,6 +30,11 @@ module Pixelflow
29
30
  @socket = TCPSocket.new('127.0.0.1', 19223)
30
31
  set_size(width, height)
31
32
  set_color_mode(color_mode) if color_mode
33
+ @last_timestamp = Time.now.to_f
34
+ end
35
+
36
+ def run(&block)
37
+ yield(self)
32
38
  end
33
39
 
34
40
  def recreate_screen()
@@ -81,17 +87,25 @@ module Pixelflow
81
87
  end
82
88
 
83
89
  def move_to(x, y)
90
+ x0 = x0.to_i
91
+ y0 = y0.to_i
92
+ x1 = x1.to_i
93
+ y1 = y1.to_i
84
94
  return if x < 0 || x >= @width || y < 0 || y >= @height
85
95
  @x = x
86
96
  @y = y
87
97
  buffer = [5].pack('C')
88
- buffer += [x].pack((@width < 256) ? 'C' : 'n')
89
- buffer += [y].pack((@height < 256) ? 'C' : 'n')
98
+ buffer += [x].pack((@width <= 256) ? 'C' : 'n')
99
+ buffer += [y].pack((@height <= 256) ? 'C' : 'n')
90
100
  @socket.write(buffer)
91
101
  @socket.flush
92
102
  end
93
103
 
94
104
  def set_pixel(x, y, r, g = 0, b = 0)
105
+ x0 = x0.to_i
106
+ y0 = y0.to_i
107
+ x1 = x1.to_i
108
+ y1 = y1.to_i
95
109
  return if x < 0 || x >= @width || y < 0 || y >= @height
96
110
  unless x == @x && y == @y
97
111
  move_to(x, y)
@@ -129,6 +143,10 @@ module Pixelflow
129
143
  end
130
144
 
131
145
  def get_pixel(x, y)
146
+ x0 = x0.to_i
147
+ y0 = y0.to_i
148
+ x1 = x1.to_i
149
+ y1 = y1.to_i
132
150
  return 0 if x < 0 || x >= @width || y < 0 || y >= @height
133
151
  if @color_mode == :rgb
134
152
  return @screen[(y * @width + x) * 3, 3]
@@ -144,5 +162,252 @@ module Pixelflow
144
162
  @socket.flush
145
163
  end
146
164
  end
165
+
166
+ def ensure_max_fps(fps)
167
+ fps1 = 1.0 / fps
168
+ t = Time.now.to_f
169
+ dt = t - @last_timestamp
170
+ sleep(fps1 - dt) if dt < fps1
171
+ @last_timestamp = t
172
+ end
173
+
174
+ def draw_rect(x0, y0, x1, y1, color)
175
+ x0 = x0.to_i
176
+ y0 = y0.to_i
177
+ x1 = x1.to_i
178
+ y1 = y1.to_i
179
+ (x0..x1).each do |x|
180
+ set_pixel(x, y0, color)
181
+ end
182
+ (x0..x1).each do |x|
183
+ set_pixel(x, y1, color)
184
+ end
185
+ (y0+1..y1-1).each do |y|
186
+ set_pixel(x0, y, color)
187
+ set_pixel(x1, y, color)
188
+ end
189
+ end
190
+
191
+ def fill_rect(x0, y0, x1, y1, color)
192
+ x0 = x0.to_i
193
+ y0 = y0.to_i
194
+ x1 = x1.to_i
195
+ y1 = y1.to_i
196
+ (y0..y1).each do |y|
197
+ (x0..x1).each do |x|
198
+ set_pixel(x, y, color)
199
+ end
200
+ end
201
+ end
202
+
203
+ def draw_line(x0, y0, x1, y1, color)
204
+ x0 = x0.to_i
205
+ y0 = y0.to_i
206
+ x1 = x1.to_i
207
+ y1 = y1.to_i
208
+ dx = (x1 - x0).abs
209
+ dy = (y1 - y0).abs
210
+ sx = x0 < x1 ? 1 : -1
211
+ sy = y0 < y1 ? 1 : -1
212
+ err = dx - dy
213
+ loop do
214
+ set_pixel(x0, y0, color)
215
+ break if x0 == x1 && y0 == y1
216
+ e2 = 2 * err
217
+ if e2 > -dy
218
+ err -= dy
219
+ x0 += sx
220
+ end
221
+ if e2 < dx
222
+ err += dx
223
+ y0 += sy
224
+ end
225
+ end
226
+ end
227
+
228
+ def draw_circle(x, y, radius, color)
229
+ x = x.to_i
230
+ y = y.to_i
231
+ radius = radius.to_i
232
+ f = 1 - radius
233
+ ddF_x = 1
234
+ ddF_y = -2 * radius
235
+ xx = 0
236
+ yy = radius
237
+ set_pixel(x, y + radius, color)
238
+ set_pixel(x, y - radius, color)
239
+ set_pixel(x + radius, y, color)
240
+ set_pixel(x - radius, y, color)
241
+ while xx < yy
242
+ if f >= 0
243
+ yy -= 1
244
+ ddF_y += 2
245
+ f += ddF_y
246
+ end
247
+ xx += 1
248
+ ddF_x += 2
249
+ f += ddF_x
250
+ set_pixel(x + xx, y + yy, color)
251
+ set_pixel(x - xx, y + yy, color)
252
+ set_pixel(x + xx, y - yy, color)
253
+ set_pixel(x - xx, y - yy, color)
254
+ set_pixel(x + yy, y + xx, color)
255
+ set_pixel(x - yy, y + xx, color)
256
+ set_pixel(x + yy, y - xx, color)
257
+ set_pixel(x - yy, y - xx, color)
258
+ end
259
+ end
260
+
261
+ def fill_circle(x, y, r, color)
262
+ x = x.to_i
263
+ y = y.to_i
264
+ r = r.to_i
265
+ f = 1 - r
266
+ ddF_x = 1
267
+ ddF_y = -2 * r
268
+ xx = 0
269
+ yy = r
270
+ (y - r..y + r).each do |i|
271
+ set_pixel(x, i, color)
272
+ end
273
+ while xx < yy
274
+ if f >= 0
275
+ yy -= 1
276
+ ddF_y += 2
277
+ f += ddF_y
278
+ end
279
+ xx += 1
280
+ ddF_x += 2
281
+ f += ddF_x
282
+ (y - yy..y + yy).each do |i|
283
+ set_pixel(x + xx, i, color)
284
+ set_pixel(x - xx, i, color)
285
+ end
286
+ (y - xx..y + xx).each do |i|
287
+ set_pixel(x + yy, i, color)
288
+ set_pixel(x - yy, i, color)
289
+ end
290
+ end
291
+ end
292
+
293
+ def draw_ellipse(x, y, a, b, color)
294
+ x = x.to_i
295
+ y = y.to_i
296
+ a = a.to_i
297
+ b = b.to_i
298
+ a2 = a * a
299
+ b2 = b * b
300
+ fa2 = 4 * a2
301
+ fb2 = 4 * b2
302
+ x0 = 0
303
+ y0 = b
304
+ sigma = 2 * b2 + a2 * (1 - 2 * b)
305
+ while b2 * x0 <= a2 * y0
306
+ set_pixel(x + x0, y + y0, color)
307
+ set_pixel(x - x0, y + y0, color)
308
+ set_pixel(x + x0, y - y0, color)
309
+ set_pixel(x - x0, y - y0, color)
310
+ if sigma >= 0
311
+ sigma += fa2 * (1 - y0)
312
+ y0 -= 1
313
+ end
314
+ sigma += b2 * ((4 * x0) + 6)
315
+ x0 += 1
316
+ end
317
+ x0 = a
318
+ y0 = 0
319
+ sigma = 2 * a2 + b2 * (1 - 2 * a)
320
+ while a2 * y0 <= b2 * x0
321
+ set_pixel(x + x0, y + y0, color)
322
+ set_pixel(x - x0, y + y0, color)
323
+ set_pixel(x + x0, y - y0, color)
324
+ set_pixel(x - x0, y - y0, color)
325
+ if sigma >= 0
326
+ sigma += fb2 * (1 - x0)
327
+ x0 -= 1
328
+ end
329
+ sigma += a2 * ((4 * y0) + 6)
330
+ y0 += 1
331
+ end
332
+ end
333
+
334
+ def fill_ellipse(x, y, a, b, color)
335
+ x = x.to_i
336
+ y = y.to_i
337
+ a = a.to_i
338
+ b = b.to_i
339
+ a2 = a * a
340
+ b2 = b * b
341
+ fa2 = 4 * a2
342
+ fb2 = 4 * b2
343
+ x0 = 0
344
+ y0 = b
345
+ sigma = 2 * b2 + a2 * (1 - 2 * b)
346
+ while b2 * x0 <= a2 * y0
347
+ (x - x0..x + x0).each do |i|
348
+ set_pixel(i, y + y0, color)
349
+ set_pixel(i, y - y0, color)
350
+ end
351
+ if sigma >= 0
352
+ sigma += fa2 * (1 - y0)
353
+ y0 -= 1
354
+ end
355
+ sigma += b2 * ((4 * x0) + 6)
356
+ x0 += 1
357
+ end
358
+ x0 = a
359
+ y0 = 0
360
+ sigma = 2 * a2 + b2 * (1 - 2 * a)
361
+ while a2 * y0 <= b2 * x0
362
+ (x - x0..x + x0).each do |i|
363
+ set_pixel(i, y + y0, color)
364
+ set_pixel(i, y - y0, color)
365
+ end
366
+ if sigma >= 0
367
+ sigma += fb2 * (1 - x0)
368
+ x0 -= 1
369
+ end
370
+ sigma += a2 * ((4 * y0) + 6)
371
+ y0 += 1
372
+ end
373
+ end
374
+
375
+ def draw_quadratic_bezier(x0, y0, x1, y1, x2, y2, color, steps = 100)
376
+ steps = steps.to_i
377
+ xp = nil
378
+ yp = nil
379
+ (0..steps).each do |i|
380
+ t = i.to_f / steps
381
+ x = (1 - t) ** 2 * x0 + 2 * (1 - t) * t * x1 + t ** 2 * x2
382
+ y = (1 - t) ** 2 * y0 + 2 * (1 - t) * t * y1 + t ** 2 * y2
383
+ if xp && yp
384
+ draw_line(xp.to_i, yp.to_i, x.to_i, y.to_i, color)
385
+ end
386
+ xp = x
387
+ yp = y
388
+ end
389
+ end
390
+
391
+ def draw_cubic_bezier(x0, y0, x1, y1, x2, y2, x3, y3, color, steps = 100)
392
+ steps = steps.to_i
393
+ xp = nil
394
+ yp = nil
395
+ (0..steps).each do |i|
396
+ t = i.to_f / steps
397
+ x = (1 - t) ** 3 * x0 + 3 * (1 - t) ** 2 * t * x1 + 3 * (1 - t) * t ** 2 * x2 + t ** 3 * x3
398
+ y = (1 - t) ** 3 * y0 + 3 * (1 - t) ** 2 * t * y1 + 3 * (1 - t) * t ** 2 * y2 + t ** 3 * y3
399
+ if xp && yp
400
+ draw_line(xp.to_i, yp.to_i, x.to_i, y.to_i, color)
401
+ end
402
+ xp = x
403
+ yp = y
404
+ end
405
+ end
406
+
407
+ def draw_triangle(x0, y0, x1, y1, x2, y2, color)
408
+ draw_line(x0, y0, x1, y1, color)
409
+ draw_line(x1, y1, x2, y2, color)
410
+ draw_line(x2, y2, x0, y0, color)
411
+ end
147
412
  end
148
413
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pixelflow_canvas
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Specht
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-10-23 00:00:00.000000000 Z
11
+ date: 2024-10-24 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Use a virtual CRT for old school graphics programming, in VS Code, from
14
14
  Ruby.