previndexinfonext

code guessing, round #54 (completed)

started at ; stage 2 at ; ended at

specification

the challenge is to implement 3d rendering. yes, really.

you have a lot of license as to how you approach this problem, and there is a large breadth of things that could be considered "3D rendering". raytracing, rasterization, calling opengl, or whatever other methods you can think of are all okay here. what you do with your solution is also up to you. you can render a reflective sphere, a triangle, or your favourite anime girl. you can even make a game or explorable area of sorts, if you're up to it.

naturally, all languages are allowed, and there is no fixed API. now excuse me as I go to whine about this problem in #event-discussion.

note: this round was originally released along with a short interactive sequence. you can still see it by clicking this button:

results

  1. 👑 kimapr +5 -1 = 4
    1. essaie
    2. luatic
    3. taswelll
    4. Dolphy
    5. LyricLy
  2. LyricLy +3 -1 = 2
    1. essaie
    2. luatic
    3. taswelll
    4. kimapr (was Dolphy)
    5. Dolphy (was kimapr)
  3. Dolphy +3 -1 = 2
    1. essaie
    2. luatic
    3. LyricLy (was taswelll)
    4. taswelll (was LyricLy)
    5. kimapr
  4. taswelll +1 -2 = -1
    1. LyricLy (was essaie)
    2. luatic
    3. kimapr (was Dolphy)
    4. Dolphy (was LyricLy)
    5. essaie (was kimapr)
  5. essaie +1 -4 = -3
    1. luatic
    2. kimapr (was taswelll)
    3. LyricLy (was Dolphy)
    4. taswelll (was LyricLy)
    5. Dolphy (was kimapr)
  6. luatic +1 -5 = -4
    1. essaie
    2. LyricLy (was taswelll)
    3. kimapr (was Dolphy)
    4. taswelll (was LyricLy)
    5. Dolphy (was kimapr)

entries

you can download all the entries

entry #1

written by essaie
submitted at
0 likes

guesses
comments 0

post a comment


three-dimensional_rendering.py ASCII text, with CRLF line terminators
  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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
from turtle import Turtle  # We will be using turtle to draw!
from turtle import Screen  # :D
import math
import time
#import space  # delete later (they mustn't learn our secrets)

dot_product = lambda v1, v2: sum(map(lambda v1i, v2i: v1i * v2i, v1, v2))
vector_add = lambda v1, v2: list(map(lambda v1i, v2i: v1i + v2i, v1, v2))
magnitude = lambda v: math.sqrt(dot_product(v, v))  # Euclidean norm!
direction = lambda v: (lambda r: [vi / r if r else 0 for vi in v]) (magnitude(v))

## --- Defining useful classes --- ##

class Vertex:
    def __init__(self, loc):  # List of numbers
        self.loc = loc
        self.dim = len(loc)

    def copy(self):
        return Vertex(self.loc)

    def rotate(self, rotation, center):  # Assume rotation is a square matrix
        targ = len(rotation)

        truncated = self.dim > targ
        if truncated:
            ws = self.loc[:targ]
        else:
            ws = self.loc + [0] * (targ - self.dim)
        
        if center.dim > targ:
            wc = center.loc[:targ]
        else:
            wc = center.loc + [0] * (targ - center.dim)
        
        pulled = vector_add( ws, [-wci for wci in wc] )
        rotated = [dot_product(pulled, ro) for ro in rotation]
        pushed = vector_add(rotated, wc)

        if truncated:
            self.loc = pushed + self.loc[targ:]
        else:
            self.loc = pushed
        self.dim = max(self.dim, targ)

    def translate(self, translation):
        if self.dim < translation.dim:
            ws = self.loc + [0] * (translation.dim - self.dim)
            wt = translation.loc
        else:
            ws = self.loc
            wt = translation.loc + [0] * (self.dim - translation.dim)

        self.loc = vector_add(ws, wt)

    def stretch(self, scale, center):  # Could be done with a matrix also
        if self.dim < center.dim:
            ws = self.loc + [0] * (center.dim - self.dim)
            wc = center.loc
        else:
            ws = self.loc
            wc = center.loc + [0] * (self.dim - center.dim)

        radius = vector_add( ws, [-wci for wci in wc] )
        self.loc = vector_add( wc, [scale * ri for ri in radius] )

    def flatten(self):
        if self.dim <3 or self.loc[2] == 0:
            sign = 0
        else:
            sign = -.02 if self.loc[2] < 0 else .02  # Magic number :P

        # Funny perspective simulation
        scale = math.exp(sign * math.sqrt(magnitude(self.loc[2:])))

        x_funny = sum(p * (-1 if i % 4 < 2 else 1) / math.sqrt(i + 3) for i, p in enumerate(self.loc[3:]))
        y_funny = sum(p * (-1 if (i + 1) % 4 < 2 else 1) / math.sqrt(i + 3) for i, p in enumerate(self.loc[3:]))

        #return (self.loc[0], self.loc[1])  # Uncomment this to get isometric stuff!
        return (scale * (self.loc[0] + x_funny), scale * (self.loc[1] + y_funny))

class Edge:
    def __init__(self, head, tail):  # Two Vertex objects
        self.head = head
        self.tail = tail

    def copy(self):
        return Edge(self.head.copy(), self.tail.copy())

    def rotate(self, rotation, center):
        self.head.rotate(rotation, center)
        self.tail.rotate(rotation, center)

    def translate(self, translation):
        self.head.translate(translation)
        self.tail.translate(translation)

    def stretch(self, scale, center):
        self.head.stretch(scale, center)
        self.tail.stretch(scale, center)

    def flatten(self):
        return (self.head.flatten(), self.tail.flatten())

class EdgeBunch:
    def __init__(self, edges, center):  # List of Edge objects
        self.lines = edges
        self.center = center
        self.verts = set([])
        for l in edges:
            self.verts.add(l.head)
            self.verts.add(l.tail)

    def copy(self):
        return EdgeBunch([l.copy() for l in self.lines], self.center.copy())
    
    def rotate(self, rotation, center):
        for line in self.lines:
            line.rotate(rotation, center)
        self.center.rotate(rotation, center)

    def translate(self, translation):
        for line in self.lines:
            line.translate(translation)
        self.center.translate(translation)

    def stretch(self, scale, center):
        for line in self.lines:
            line.stretch(scale, center)
        self.center.stretch(scale, center)

    def flatten(self):
        return (line.flatten() for line in self.lines)  # Iterator is easier later!

    def absorb(self, other):
        for line in other.lines:
            self.lines.append(line.copy())

class Programme:
    def __init__(self, cast, script):
        self.cast = cast      # List of EdgeBunch objects
        self.script = script  # List of tuples
    
    def do(self):
        for who, action, args, reps in self.script:
            thing = self.cast[who]
            call = len(args)
            for i in range(reps):
                time.sleep(.05)
                t.clear()
                if call == 2:
                    eval("thing." + action + "(args[0], args[1])")
                elif call == 3:
                    eval("thing." + action + "(args[0], args[1], args[2])")
                else:
                    raise ValueError()  # I really can't be bothered
                draw(t, thing)          # see?

## --- Defining useful functions --- ##

# These ones are the shape-makers

def regular_polygon(sides, radius, center):
    first = Vertex([0, radius])
    first.translate(center)
    
    points = [first]
    angle = 2 * math.pi / sides
    turn = [[math.cos(angle), -math.sin(angle)],
            [math.sin(angle),  math.cos(angle)]]
    for i in range(sides - 1):
        another = points[-1].copy()
        another.rotate(turn, center)
        points.append(another)

    return EdgeBunch([Edge(points[i - 1], points[i]) for i in range(sides)], center.copy())

def new_simplex(radius, center, dim):  # May not actually, er, be centered at the center :P
    if dim == 2:
        return regular_polygon(3, radius, center.copy())
    prev = new_simplex(radius * math.sqrt(1 - (1 / dim)**2), center, dim - 1)
    depth = [0] * (dim - 1) + [- 1 / dim]
    prev.translate(Vertex(depth))
    addition = Vertex(depth[ :-1 ] + [radius])
    lines = []
    for line in prev.lines:
        lines.append(line)
    for point in prev.verts:
        lines.append(Edge(addition, point))
    
    return EdgeBunch(lines, center.copy())

def new_cube(radius, center, dim):
    if dim == 2:
        return regular_polygon(4, radius, center.copy())
    halfside = radius / math.sqrt(dim)
    #print(radius, halfside)
    near = new_cube(halfside * math.sqrt(dim - 1), center, dim - 1)
    far = near.copy()
    depth = [0] * (dim - 1)
    near.translate(Vertex(depth + [halfside/2]))  # This doesn't make sense
    far.translate(Vertex(depth + [-halfside]))
    lines = []
    for nline, fline in zip(near.lines, far.lines):
        lines.append(Edge(nline.tail.copy(), fline.tail.copy()))
        lines.append(nline.copy())
        lines.append(fline.copy())
    frame = EdgeBunch(list(set(lines)), center.copy())

    return frame

def new_orthoplex(radius, center, dim):
    if dim == 2:
        return regular_polygon(4, radius, center)
    base = new_orthoplex(radius, center, dim - 1)
    above = Vertex([0] * (dim - 1) + [radius])
    below = Vertex([0] * (dim - 1) +[-radius])
    lines = []
    for vert in base.verts:
        lines.append(Edge(above.copy(), vert.copy()))
        lines.append(Edge(below.copy(), vert.copy()))
    pot = EdgeBunch(lines, center.copy())
    pot.absorb(base)

    return pot

def tetrahedron(radius, center):
    return new_simplex(radius, center, 3)

def hexahedron(radius, center):
    return new_cube(radius, center, 3)

def octahedron(radius, center):
    return new_orthoplex(radius, center, 3)

def icosahedron(radius, center):
    phi = (1 + math.sqrt(5)) / 2
    pent_rad = math.sqrt((5 + math.sqrt(5)) / 10) * radius
    top = regular_polygon(5, pent_rad, center)
    bottom = regular_polygon(5, pent_rad, center) # (;
    angle = 9 * math.pi / 10
    turn = [[math.cos(angle), -math.sin(angle)],
            [math.sin(angle),  math.cos(angle)]]
    bottom.rotate(turn, center) # ;)
    top.translate(Vertex([0, 0, radius * math.sqrt(3) / 8]))
    bottom.translate(Vertex([0, 0, -radius * math.sqrt(3) / 8]))
    crown = Vertex([0, 0, radius * math.sqrt(phi**2 + 1) / 2])
    boots = Vertex([0, 0,-radius * math.sqrt(phi**2 + 1) / 2])
    lines = []
    for tline, bline in zip(top.lines, bottom.lines):
        lines.append(tline.copy())
        lines.append(bline.copy())
        lines.append(Edge(tline.head.copy(), bline.head.copy()))
        lines.append(Edge(tline.head.copy(), bline.tail.copy()))
        lines.append(Edge(tline.head.copy(), crown.copy()))
        lines.append(Edge(bline.tail.copy(), boots.copy()))

    return EdgeBunch(lines, center.copy())

def dodecahedron(radius, center):  # Bleh.
    pass

def pentachoron(radius, center):
    return new_simplex(radius, center, 4)

def octachoron(radius, center):
    return new_cube(radius, center, 4)

def hexadecachoron(radius, center):
    return new_orthoplex(radius, center, 4)

def icositetrachoron(radius, center):
    pass

def dodecacontachoron(radius, center):  # Sorry, 120-cell.
    pass

def hexacosichoron(radius, center):
    pass

# These ones are the water closets

def draw_line(t, line, color=None):
    head, tail = line
    if color: t.pencolor(color)
    t.pu()
    t.goto(head[0], head[1])
    t.pd()
    t.goto(tail[0], tail[1])

def draw(t, edgebunch, color=None):
    for line in edgebunch.flatten():
        draw_line(t, line, color)

def next_render(x, y):
    global track_number, programmes
    track_number = (track_number + 1) % len(programmes)

def prev_render(x, y):
    global track_number, programmes
    track_number = (track_number - 1) % len(programmes)

## --- Starting the Turtle stuff --- ##

s = Screen()
H = s.window_height()
W = s.window_width()
s.setworldcoordinates(- W / 2, - H / 2,
                        W / 2,   H / 2)
s.delay(0)
t = Turtle()
t.speed(0)
t.ht()

s.title("Click to change model! Escape to escape!")
s.onkey(s.bye, "Escape")
s.onclick(next_render, btn=1)
s.onclick(prev_render, btn=2)
s.listen()

## --- Everything we will be showcasing! --- ##

track_number = 0
programmes = []

origin = Vertex([0, 0])
lpoint = Vertex([-75, 0])
rpoint = Vertex([0,  75])
test_rotat = [
    [math.cos(math.pi/58), 0, math.sin(math.pi/58)],
    [             0, 1, 0],
    [-math.sin(math.pi/58), 0, math.cos(math.pi/58)]
]
fast_rotat = [
    [math.cos(math.pi/18), 0, math.sin(math.pi/18)],
    [             0, 1, 0],
    [-math.sin(math.pi/18), 0, math.cos(math.pi/18)]
]
oter_rotat = [
    [math.cos(math.pi/48), -math.sin(math.pi/48), 0],
    [math.sin(math.pi/48),  math.cos(math.pi/48), 0],
    [              0,              0, 1]
]

four_rotat = [
    [math.cos(math.pi/58), 0, -math.sin(math.pi/58), 0],
    [0, math.cos(math.pi/38), 0, -math.sin(math.pi/38)],
    [math.sin(math.pi/58),  0, math.cos(math.pi/58), 0],
    [0, math.sin(math.pi/38), 0,  math.cos(math.pi/38)],
]

square_rotating = Programme([regular_polygon(4, 300, origin)], [(0, 'rotate', [oter_rotat, origin], 1)])

square_3d = Programme([regular_polygon(4, 300, origin)], [(0, 'rotate', [test_rotat, origin], 1)])

funny_square = regular_polygon(4, 150/math.sqrt(2), lpoint)
funny_square.rotate([[math.cos(math.pi/8),-math.sin(math.pi/8)],[math.sin(math.pi/8),math.cos(math.pi/8)]], lpoint)
funny_rotate = Programme([funny_square], [
    (0, 'rotate', [fast_rotat, rpoint], 7),
    (0, 'rotate', [fast_rotat, lpoint], 7)])

boring_tetra = Programme([new_simplex(200, origin, 3)], [(0, 'rotate', [test_rotat, origin], 1)])

fun_cube = Programme([icosahedron(200, origin)], [(0, 'rotate', [test_rotat, origin], 1)])

actual_cube = Programme([new_cube(200, origin, 3)], [(0, 'rotate', [test_rotat, origin], 1), (0, 'rotate', [oter_rotat, origin], 1)])

roll_d8 = Programme([new_orthoplex(200, origin, 3)], [(0, 'rotate', [test_rotat, origin], 1), (0, 'rotate', [oter_rotat, origin], 1)])

guess_what = Programme([new_cube(200, origin, 4)], [(0, 'rotate', [four_rotat, origin], 1), (0, 'rotate', [oter_rotat, origin], 1)])

i_am_going_insane = Programme([new_simplex(200, origin, 4)], [(0, 'rotate', [four_rotat, origin], 1), (0, 'rotate', [oter_rotat, origin], 1)])

#please_send_help = Programme([new_orthoplex(200, origin, 4)], [(0, 'rotate', [four_rotat, origin], 1), (0, 'rotate', [oter_rotat, origin], 1)])
# Lol this one isn't working nicely

programmes = [
    square_rotating,
    square_3d,
    funny_rotate,
    boring_tetra,
    fun_cube,
    actual_cube,
    roll_d8,
    guess_what,
    i_am_going_insane,
    #please_send_help,
]

while True:
    programmes[track_number].do()

# With some modification, you can easily make your own programmes!
# There's room available for shows with multiple actors, if you can get
# turtle drawing fast enough :3

entry #2

written by luatic
submitted at
0 likes

guesses
comments 0

post a comment


bnuuy.tar.paq8px208fix1 data

entry #3

written by taswelll
submitted at
1 like

guesses
comments 1
jan Sija

You can run this online at https://rabbits.srht.site/uxn5/


post a comment


entry.rom data
entry.tal ASCII text
  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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
( devices )
|00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 &debug $1 ]
|10 @Console [ &vector $2 &read $1 &pad $4 &type $1 &write $1 &error $1 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
|90 @Mouse [ &vector $2 &x $2 &y $2 &state $1 &pad $7 &scrolly $1 ]

|00 @pressed $1 @shape $2
%BLIT { .Screen/y DEO2 .Screen/x DEO2 #42 .Screen/pixel DEO }

%ABS2 { DUP2k #1f SFT2 MUL2 SUB2 }
%NOT { #01 EOR }
%NEG { #ff MUL }
%NEG2 { #ffff MUL2 }

%DBG { #01 .System/debug DEO }
%ISNEG2 { #0f SFT2 NIP }
%ISPOS2 { POP #80 LTH }
%DBL2 { #10 SFT2 }
%SGN2 { #1f SFT2 #0001 SWP2 SUB2 }

|0100
	#0f7f .System/r DEO2
	#0fd6 .System/g DEO2
	#0fb2 .System/b DEO2
	( .Screen/width DEO2 )
	#00 .pressed STZ
	;shapes .shape STZ2
	
	;on-mouse .Mouse/vector DEO2

@on-mouse ( -> )
	#0000 DUP2 .Screen/y DEO2 .Screen/x DEO2 #c0 .Screen/pixel DEO
	.Mouse/state DEI #01 AND DUP NOT ?&nopress 
		.pressed LDZ ?&nopress
		.shape LDZ2 INC2 INC2 INC2 LDA2k
		#0000 NEQ2 ?&noreset POP2 ;shapes &noreset
		.shape STZ2
	&nopress .pressed STZ
	.Mouse/x DEI2 #20 SFT2 display
	BRK

@smul21 ( x* y* -- x.y* )
	STH2 DUP2 SGN2 DUP2 ROT2 MUL2 ( xs* |x|* | y* )
	STH2r DUP2 SGN2 DUP2 ROT2 MUL2 ( xs* |x|* ys* |y|* )
	ROT2 SWP2 mul21 [ STH2 MUL2 STH2r ] MUL2 ( ys.xs.|x|.|y|* ) 
JMP2r

@mul21 ( x* y* -- x.y* )
	( OVR #80 LTH  ?&pos NEG2 mul21 JMP2r &pos )
	ROT #00 SWP ( OVR ,&meow STR ) OVR2 MUL2 ( xh y* xl.y* )
	POP STH ( xh y* | xl.y>>8 )
	ROT #00 SWP  [ MUL2 #00 STHr ] ADD2
JMP2r
%LTS2 { #8000 STH2k ADD2 SWP2 STH2r ADD2 GTH2 }
%GTS2 { #8000 STH2k ADD2 SWP2 STH2r ADD2 LTH2 }
%PI/2 { #0192 } %PI { #0324 } %2.PI { #0648 } %nPI/2 { #fe6d }
( 0x1234 0x5678 )
@cos ( x* -- cos* )
	DUP2 nPI/2 GTS2 ?&noadd 2.PI ADD2 !cos &noadd
	DUP2 PI/2 LTS2 ?&noneg PI SUB2 /noadd NEG2 JMP2r &noneg
	ABS2 DUP2 mul21 #01 SFT2 ( x^2/2* )
	DUP2k mul21 #0028 ( ~1/6 ) mul21 ( x^2/2* x^4/24* )
	SUB2 #0100 SWP2 SUB2
JMP2r
@sin ( x* -- cos* ) PI/2 SUB2 cos JMP2r

@rotate ( x* y* phi* -- x'* y'* )
	DUP2 sin STH2 cos STH2 SWP2k  ( x y y x | sin cos )
	STH2kr SWP2r smul21 SWP2 STH2kr smul21 ADD2 ( x y y.cos+x.sin | cos sin )
	STH2r STH2r ROT2 STH2 ROT2 ( x cos sin y | y.cos+x.sin )
	smul21 STH2 smul21 STH2r SWP2 SUB2 ( x.cos-y.sin | y.cos+x.sin )
	STH2r
JMP2r

%V3 { #01bb }
@project ( x* y* z* -- x'* y'* )
	STH2 
	OVR2 V3 smul21 OVR2 V3 smul21 SUB2 ( x* y* V3.x-V3.y | z* )
	ROT2 ROT2 ADD2 STH2r DBL2 SUB2 ( V3.x-V3.y x+y-2.z )
JMP2r
@display ( phi* -- )
	STH2 .shape LDZ2 LDA2k STH2
	INC2 INC2 LDA #00 &until LTHk ?&end
		STH2r point STH2kr SWP2 STH2 ( x1* y1* phi* | phi* addr* )
		transform ( x1* y1* addr* | phi* )
		STH2r point STH2kr SWP2 STH2 ( x1* x2* y1* y2* phi* | phi* addr* )
		transform ( x1* x2* y1* y2* | phi* addr* )
		Bresenham/draw
	INC !&until &end
	POP2 POP2r POP2r
	JMP2r
@point ( addr* -- x* y* z* addr* )
	%read { LDAk #00 #50 SFT2 SWP #0020 SUB2 SWP2 INC2 }  read read read JMP2r
@transform ( x* y* z* phi* -- x* y* )
	SWP2 STH2 ( x* y* phi* | z* ) rotate STH2r project
	.Screen/height DEI2 #01 SFT2 ADD2
	[ STH2 .Screen/width DEI2 #01 SFT2 ADD2 STH2r ]
JMP2r

@shapes =&shape1 11 =&shape2 0b 00 00 ( add more! )
	&shape1
		[
		00 00 00  02 00 00
		02 00 00  02 02 00
		02 02 00  00 02 00
		00 02 00  00 00 00 ]
		[
		00 00 00  00 00 02
		00 00 02  01 00 02
		01 00 02  01 00 01
		01 00 01  02 00 01
		02 00 01  02 00 00 ]
		[
		00 02 00  00 02 02
		00 02 02  01 02 02
		01 02 02  01 02 01
		01 02 01  02 02 01
		02 02 01  02 02 00 ]
		[
		02 00 01  02 02 01
		01 00 01  01 02 01
		01 00 02  01 02 02
		00 00 02  00 02 02 ]
	&shape2
		[
		01 01 00  00 01 01
		01 01 00  02 01 01
		01 01 00  01 00 01
		01 01 00  01 02 01
		01 01 02  00 01 01
		01 01 02  02 01 01
		01 01 02  01 00 01
		01 01 02  01 02 01 ]
		[
		01 00 01  00 01 01
		01 02 01  00 01 01
		01 00 01  02 01 01
		01 02 01  02 01 01 ]

@Bresenham
&draw ( x0* y0* x1* y1* -> )
	STH2 SWP2 STH2 SWP2r ( x0* x1* | y0* y1* )
	SWP2 OVR2 SWP2r OVR2r ( x1* x0* x1* | y1* y0* y1* )
	OVR2 SUB2 OVR2r SUB2r ( x1* x0* dx* | y1* y0* dy* )
	( flip points if appropriate )
	STH2kr OVR2 ADD2 ISPOS2 ?&noflip
		NEG2 ROT2 SWP2 ( x1* x0* dx* -> x0* x1* -dx* )
		STH2r NEG2 STH2 ROT2r SWP2r ( y1* y0* dy* -> y0* y1* -dy* )
	&noflip
	LIT POPk ,&blitswap STR
	STH2kr ABS2 OVR2 SUB2 ISNEG2 ?&noswap
		( x1* x0* dx* | y1* y0* dy* )
		;&dy STA2 STH2r ,&dx STR2 NIP2 ( x0* | y1* y0* )
		STH2r STH2r ROT2 STH2 SWP2 ( y1* y0* | x0* )
		LIT SWP2 ,&blitswap STR 
	!&stopswap &noswap
		( x1* x0* dx* | y1* y0* dy* )
		,&dx STR2 STH2r ,&dy STR2 NIP2r ( x1* x0* | y0* )
	&stopswap
	( x1* x0* | y0* ) 
	,&dy LDR2 DUP2
	#1f SFT2 ( dy>>16<<1 = 2(dy<0) )
	#0001 SWP2 SUB2 ( dy<0: 1-2 = -1; dy>=0: 1-0 = 1 )
	DUP2 ,&dysgn STR2 ( sign of dy.  1 going up, -1 going down )
	MUL2 DUP2 ,&dy STR2 ( dy:=abs(dy) )
	DBL2 ,&dx LDR2 SUB2 ,&diff STR2 ( diff := 2dy - dx.  x0* | y0* )
	( loop is about to start!  x1* x* | y* ) 
	&while LTH2k ( x < x1 ) ?&ent
		STH2r OVR2 OVR2 &blitswap POPk BLIT ( x* y* )
		,&diff LDR2 #0001 SUB2 ISNEG2 ?&nosft ( x-1<0 <-> x<=0 most of the time )
			LIT2 &dysgn $2 ADD2 
			,&dy LDR2 ,&dx LDR2 SUB2 DBL2 ( x* y* 2(dy-dx) ) !&after
		&nosft
			,&dy LDR2 DBL2
		&after
		;&diff LDA2k ROT2 ADD2 SWP2 STA2 ( diff := diff+2dy )
		STH2 INC2 !&while
	&ent
	POP2r POP2 POP2 
JMP2r
&dx $2 &dy $2 &diff $2

entry #4

written by Dolphy
submitted at
0 likes

guesses
comments 2
olus2000

You can run this online at https://www.pico-8-edu.com/


🥺 replying to olus2000

thanks you olus two thousands


post a comment


3drenderer.p8.png PNG image data, 160 x 205, 8-bit/color RGBA, non-interlaced

entry #5

written by LyricLy
submitted at
1 like

guesses
comments 0

post a comment


ray.bqn Unicode text, UTF-8 text
1
•Show (" #"˜)¨´¨((´(5≥⊢)((-5)≤⊢)((-6)(-6)(-7)+⊢))¨(100)×)¨10÷˜{𝕩3}¨((↕⋈)-(2˜÷))15

entry #6

written by kimapr
submitted at
0 likes

guesses
comments 2
olus2000

This can be executed online at https://www.pico-8-edu.com/


soweli Lomjo

however what illumination pierces through that distant aperture its the olus yet its a deceit the trickery originates from the east shattering my heart with its untrue nature


post a comment


cg54.p8.png PNG image data, 160 x 205, 8-bit/color RGBA, non-interlaced