September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -5,5 +5,6 @@ Either static or rotational projection is acceptable for this task.
<br><br>
;Related tasks
* [[Draw_a_rotating_cube|Draw a rotating cube]]
* [[Draw_a_rotating_cube|draw a rotating cube]]
* [[Write_language_name_in_3D_ASCII|write language name in 3D ASCII]]
<br><br>

View file

@ -1,136 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
const char *shades = ".:!*oe&#%@";
void vsub(double *v1, double *v2, double *s) {
s[0] = v1[0] - v2[0];
s[1] = v1[1] - v2[1];
s[2] = v1[2] - v2[2];
}
double normalize(double * v) {
double len = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
v[0] /= len; v[1] /= len; v[2] /= len;
return len;
}
double dot(double *x, double *y) {
return x[0]*y[0] + x[1]*y[1] + x[2]*y[2];
}
double * cross(double x[3], double y[3], double s[3]) {
s[0] = x[1] * y[2] - x[2] * y[1];
s[1] = x[2] * y[0] - x[0] * y[2];
s[2] = x[0] * y[1] - x[1] * y[0];
return s;
}
double* madd(double *x, double *y, double d, double *r) {
r[0] = x[0] + y[0] * d;
r[1] = x[1] + y[1] * d;
r[2] = x[2] + y[2] * d;
return r;
}
double v000[] = { -4, -3, -2 };
double v100[] = { 4, -3, -2 };
double v010[] = { -4, 3, -2 };
double v110[] = { 4, 3, -2 };
double v001[] = { -4, -3, 2 };
double v101[] = { 4, -3, 2 };
double v011[] = { -4, 3, 2 };
double v111[] = { 4, 3, 2 };
typedef struct {
double * v[4];
double norm[3];
} face_t;
face_t f[] = {
{ { v000, v010, v110, v100 }, { 0, 0, -1 } },
{ { v001, v011, v111, v101 }, { 0, 0, 1 } },
{ { v000, v010, v011, v001 }, { -1, 0, 0 } },
{ { v100, v110, v111, v101 }, { 1, 0, 0 } },
{ { v000, v100, v101, v001 }, { 0, -1, 0 } },
{ { v010, v110, v111, v011 }, { 0, 1, 0 } },
};
int in_range(double x, double x0, double x1) {
return (x - x0) * (x - x1) <= 0;
}
int face_hit(face_t *face, double src[3], double dir[3], double hit[3], double *d)
{
int i;
double dist;
for (i = 0; i < 3; i++)
if (face->norm[i])
dist = (face->v[0][i] - src[i]) / dir[i];
madd(src, dir, dist, hit);
*d = fabs(dot(dir, face->norm) * dist);
if (face->norm[0]) {
return in_range(hit[1], face->v[0][1], face->v[2][1]) &&
in_range(hit[2], face->v[0][2], face->v[2][2]);
}
else if (face->norm[1]) {
return in_range(hit[0], face->v[0][0], face->v[2][0]) &&
in_range(hit[2], face->v[0][2], face->v[2][2]);
}
else if (face->norm[2]) {
return in_range(hit[0], face->v[0][0], face->v[2][0]) &&
in_range(hit[1], face->v[0][1], face->v[2][1]);
}
return 0;
}
int main()
{
int i, j, k;
double eye[3] = { 7, 7, 6 };
double dir[3] = { -1, -1, -1 }, orig[3] = {0, 0, 0};
double hit[3], dx[3], dy[3] = {0, 0, 1}, proj[3];
double d, *norm, dbest, b;
double light[3] = { 6, 8, 6 }, ldist[3], decay, strength = 10;
normalize(cross(eye, dy, dx));
normalize(cross(eye, dx, dy));
for (i = -10; i <= 17; i++) {
for (j = -35; j < 35; j++) {
vsub(orig, orig, proj);
madd(madd(proj, dx, j / 6., proj), dy, i/3., proj);
vsub(proj, eye, dir);
dbest = 1e100;
norm = 0;
for (k = 0; k < 6; k++) {
if (!face_hit(f + k, eye, dir, hit, &d)) continue;
if (dbest > d) {
dbest = d;
norm = f[k].norm;
}
}
if (!norm) {
putchar(' ');
continue;
}
vsub(light, hit, ldist);
decay = normalize(ldist);
b = dot(norm, ldist) / decay * strength;
if (b < 0) b = 0;
else if (b > 1) b = 1;
b += .2;
if (b > 1) b = 0;
else b = 1 - b;
putchar(shades[(int)(b * (sizeof(shades) - 2))]);
}
putchar('\n');
}
return 0;
}

View file

@ -1,28 +0,0 @@
*
**************!!
*************!!!!!!!!!!!!!!!!!!
ooo************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*oooo***********!!!!!!!!!!!!!!!!!::::::::::::::::::::!!!
o*************!!!!!!!!!!!!:::::::::::::::::::::::::::::::::::::
o****!!****!!!!!!!!!!:::::::::::::::::::::::::::::::::::::::::&&
oo****!!!!:!!!!!!!::::::::::::::::.................::::::::e&&&
o*****!!!!:::!!!:::::::::::............................eee&&&&
oo*****!!!!:::...:::::::.............................eeeee&&&
oo*****!!!!:::.....::............................oeeeeee&&&
ooo*****!!!!:::...............................ooooeeeee&&&&
ooo*****!!!!:::...........................ooooooeeeeee&&&
oooo*****!!!!::::......................**ooooooeeeeee&&&&
ooo*****!!!!::::..................****ooooooeeeeee&&&&
oo*****!!!!::::...............*****oooooooeeeeee&&&&
o*****!!!!::::..............****oooooooeeeeee&&&&
*****!!!!:::::............***oooooooeeeeee&&&
***!!!!!::::...........**oooooooeeeeee&&
***!!!!:::::.........ooooooooeeeeeee
**!!!!!::::........oooooooeeeeee
*!!!!!:::::.....oooooooeeeee
!!!!!::::....oooooeeeee
!!!!:::::..ooooeeeee
!!!!:::::oooeeee
!!!!:::oeeee
!!!::eee
!ee

View file

@ -0,0 +1,104 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
canvas {
background-color: black;
}
</style>
</head>
<body>
<canvas></canvas>
<script>
var canvas = document.querySelector("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var g = canvas.getContext("2d");
canvas.addEventListener("mousemove", function (event) {
prevMouseX = mouseX;
prevMouseY = mouseY;
mouseX = event.clientX;
mouseY = event.clientY;
var incrX = (mouseX - prevMouseX) * 0.01;
var incrY = (mouseY - prevMouseY) * 0.01;
rotateCuboid(incrX, incrY);
drawCuboid();
});
var nodes = [[-1, -1, -1], [-1, -1, 1], [-1, 1, -1], [-1, 1, 1],
[1, -1, -1], [1, -1, 1], [1, 1, -1], [1, 1, 1]];
var edges = [[0, 1], [1, 3], [3, 2], [2, 0], [4, 5], [5, 7], [7, 6],
[6, 4], [0, 4], [1, 5], [2, 6], [3, 7]];
var mouseX = 0, prevMouseX, mouseY = 0, prevMouseY;
function scale(factor0, factor1, factor2) {
nodes.forEach(function (node) {
node[0] *= factor0;
node[1] *= factor1;
node[2] *= factor2;
});
}
function rotateCuboid(angleX, angleY) {
var sinX = Math.sin(angleX);
var cosX = Math.cos(angleX);
var sinY = Math.sin(angleY);
var cosY = Math.cos(angleY);
nodes.forEach(function (node) {
var x = node[0];
var y = node[1];
var z = node[2];
node[0] = x * cosX - z * sinX;
node[2] = z * cosX + x * sinX;
z = node[2];
node[1] = y * cosY - z * sinY;
node[2] = z * cosY + y * sinY;
});
}
function drawCuboid() {
g.save();
g.clearRect(0, 0, canvas.width, canvas.height);
g.translate(canvas.width / 2, canvas.height / 2);
g.strokeStyle = "#FFFFFF";
g.beginPath();
edges.forEach(function (edge) {
var p1 = nodes[edge[0]];
var p2 = nodes[edge[1]];
g.moveTo(p1[0], p1[1]);
g.lineTo(p2[0], p2[1]);
});
g.closePath();
g.stroke();
g.restore();
}
scale(80, 120, 160);
rotateCuboid(Math.PI / 5, Math.PI / 9);
</script>
</body>
</html>

View file

@ -0,0 +1,123 @@
// version 1.1
import java.awt.*
import java.awt.event.MouseAdapter
import java.awt.event.MouseEvent
import javax.swing.*
class Cuboid: JPanel() {
private val nodes = arrayOf(
doubleArrayOf(-1.0, -1.0, -1.0),
doubleArrayOf(-1.0, -1.0, 1.0),
doubleArrayOf(-1.0, 1.0, -1.0),
doubleArrayOf(-1.0, 1.0, 1.0),
doubleArrayOf( 1.0, -1.0, -1.0),
doubleArrayOf( 1.0, -1.0, 1.0),
doubleArrayOf( 1.0, 1.0, -1.0),
doubleArrayOf( 1.0, 1.0, 1.0)
)
private val edges = arrayOf(
intArrayOf(0, 1),
intArrayOf(1, 3),
intArrayOf(3, 2),
intArrayOf(2, 0),
intArrayOf(4, 5),
intArrayOf(5, 7),
intArrayOf(7, 6),
intArrayOf(6, 4),
intArrayOf(0, 4),
intArrayOf(1, 5),
intArrayOf(2, 6),
intArrayOf(3, 7)
)
private var mouseX: Int = 0
private var prevMouseX: Int = 0
private var mouseY: Int = 0
private var prevMouseY: Int = 0
init {
preferredSize = Dimension(640, 640)
background = Color.white
scale(80.0, 120.0, 160.0)
rotateCube(Math.PI / 5.0, Math.PI / 9.0)
addMouseListener(object: MouseAdapter() {
override fun mousePressed(e: MouseEvent) {
mouseX = e.x
mouseY = e.y
}
})
addMouseMotionListener(object: MouseAdapter() {
override fun mouseDragged(e: MouseEvent) {
prevMouseX = mouseX
prevMouseY = mouseY
mouseX = e.x
mouseY = e.y
val incrX = (mouseX - prevMouseX) * 0.01
val incrY = (mouseY - prevMouseY) * 0.01
rotateCube(incrX, incrY)
repaint()
}
})
}
private fun scale(sx: Double, sy: Double, sz: Double) {
for (node in nodes) {
node[0] *= sx
node[1] *= sy
node[2] *= sz
}
}
private fun rotateCube(angleX: Double, angleY: Double) {
val sinX = Math.sin(angleX)
val cosX = Math.cos(angleX)
val sinY = Math.sin(angleY)
val cosY = Math.cos(angleY)
for (node in nodes) {
val x = node[0]
val y = node[1]
var z = node[2]
node[0] = x * cosX - z * sinX
node[2] = z * cosX + x * sinX
z = node[2]
node[1] = y * cosY - z * sinY
node[2] = z * cosY + y * sinY
}
}
private fun drawCube(g: Graphics2D) {
g.translate(width / 2, height / 2)
for (edge in edges) {
val xy1 = nodes[edge[0]]
val xy2 = nodes[edge[1]]
g.drawLine(Math.round(xy1[0]).toInt(), Math.round(xy1[1]).toInt(),
Math.round(xy2[0]).toInt(), Math.round(xy2[1]).toInt())
}
for (node in nodes) {
g.fillOval(Math.round(node[0]).toInt() - 4, Math.round(node[1]).toInt() - 4, 8, 8)
}
}
override public fun paintComponent(gg: Graphics) {
super.paintComponent(gg)
val g = gg as Graphics2D
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
g.color = Color.blue
drawCube(g)
}
}
fun main(args: Array<String>) {
SwingUtilities.invokeLater {
val f = JFrame()
f.defaultCloseOperation = JFrame.EXIT_ON_CLOSE
f.title = "Cuboid"
f.isResizable = false
f.add(Cuboid(), BorderLayout.CENTER)
f.pack()
f.setLocationRelativeTo(null)
f.isVisible = true
}
}

View file

@ -1,17 +1,10 @@
include ..\arwen\arwen.ew
include ..\arwen\axtra.ew
--
-- demo\rosetta\draw_cuboid.exw
--
include pGUI.e
constant main = create(Window, "Draw Cuboid", 0, 0, 20, 20, 625, 690, 0),
mainDC = getPrivateDC(main),
backDC = c_func(xCreateCompatibleDC, {NULL}), -- the background
viewDC = c_func(xCreateCompatibleDC, {NULL}), -- with animation
grey = #909090
constant MainTimer = createTimer()
integer dw = 0, dh = 0 -- client area width and height
atom bmBack, bmView
integer bmX = 0, bmY = 0 -- actual size of the bitmaps
Ihandle dlg, canvas, hTimer
cdCanvas cd_canvas
-- arrays: 3D coordinates of vertices
sequence x = {-2.0, +2.0, +2.0, -2.0, -2.0, +2.0, +2.0, -2.0},
@ -19,58 +12,130 @@ sequence x = {-2.0, +2.0, +2.0, -2.0, -2.0, +2.0, +2.0, -2.0},
z = {-1.0, -1.0, -1.0, -1.0, +1.0, +1.0, +1.0, +1.0},
Segment = {1,2, 2,3, 3,4, 4,1, 5,6, 6,7, 7,8, 8,5, 1,5, 2,6, 3,7, 4,8}
constant Size=50.0, Sz=0.008, Sx=-0.013 -- drawing size and tumbling speeds
atom Size = 50.0, -- drawing size
Sz = 0.008, -- tumbling speeds
Sx =-0.013, -- ""
Sy =-0.013, -- ""
S = 2
function mainHandler(integer id, integer msg, atom wParam, object lParam)
atom farthest
integer v1, v2, farv, c
if msg=WM_SIZE then
{{},{},dw,dh} = getClientRect(main)
if dw>bmX or dh>bmY then
-- we need bigger bitmaps
bmBack = c_func(xCreateCompatibleBitmap, {mainDC, dw, dh})
{} = deleteObject(selectObject(backDC,bmBack))
-- clear the background
setPenColor(grey)
setPenBkColor(grey)
drawRectangleh(backDC, True, 0, 0, dw, dh)
bmView = c_func(xCreateCompatibleBitmap, {mainDC, dw, dh})
{} = deleteObject(selectObject(viewDC,bmView))
{bmX,bmY} = {dw,dh}
procedure draw_cube(integer wx, wh)
atom farthest = 0.0 -- find the farthest vertex
integer farv, v1, v2, c, style
for i=1 to 8 do
if z[i]>farthest then farthest = z[i] farv = i end if
end for
for v=1 to 2*12 by 2 do -- for all the vertices...
v1 = Segment[v] -- get vertex number
v2 = Segment[v+1]
c = CD_RED
style = CD_CONTINUOUS
if v1=farv or v2=farv then
c = CD_BLUE
style = CD_DASHED
end if
elsif msg=WM_PAINT then
-- start with a fresh copy of the background
void = c_func(xBitBlt,{viewDC,0,0,dw,dh,backDC,0,0,SRCCOPY})
farthest = 0.0 -- find the farthest vertex
for i=1 to 8 do
if z[i]>farthest then farthest = z[i] farv = i end if
end for
for v=1 to 2*12 by 2 do -- for all the vertices...
v1 = Segment[v] -- get vertex number
v2 = Segment[v+1]
c = Red; setPenStyle(Solid)
if v1=farv or v2=farv then c=Blue; setPenStyle(Dash) end if
drawLinesh(viewDC,{c,{x[v1]*Size+dw/2, y[v1]*Size+dh/2,
x[v2]*Size+dw/2, y[v2]*Size+dh/2}})
end for
void = c_func(xBitBlt,{mainDC,0,0,dw,dh,viewDC,0,0,SRCCOPY})
elsif msg=WM_TIMER then
for i=1 to 8 do
x[i] = x[i]+y[i]*Sz -- rotate vertices in X-Y plane
y[i] = y[i]-x[i]*Sz
y[i] = y[i]+z[i]*Sx -- rotate vertices in Y-Z plane
z[i] = z[i]-y[i]*Sx
end for
repaintWindow(main)
elsif msg=WM_SHOWWINDOW then
startTimer(MainTimer,main,33)
elsif msg=WM_CHAR
and wParam=VK_ESCAPE then
closeWindow(main)
if id or object(lParam) then end if -- suppress warnings
end if
return 0
end function
setHandler({main},routine_id("mainHandler"))
cdCanvasSetForeground(cd_canvas, c)
cdCanvasLineStyle(cd_canvas, style)
atom x1 = x[v1]*Size+wx,
y1 = y[v1]*Size+wh,
x2 = x[v2]*Size+wx,
y2 = y[v2]*Size+wh
cdCanvasLine(cd_canvas,x1,y1,x2,y2)
end for
end procedure
WinMain(main, SW_NORMAL)
function canvas_action_cb(Ihandle canvas)
cdCanvasActivate(cd_canvas)
cdCanvasClear(cd_canvas)
integer {wx, wh} = sq_floor_div(IupGetIntInt(canvas, "DRAWSIZE"),2)
draw_cube(wx,wh)
cdCanvasFlush(cd_canvas)
return IUP_DEFAULT
end function
function canvas_map_cb(Ihandle canvas)
atom res = IupGetDouble(NULL, "SCREENDPI")/25.4
IupGLMakeCurrent(canvas)
cd_canvas = cdCreateCanvas(CD_GL, "10x10 %g", {res})
cdCanvasSetBackground(cd_canvas, CD_BLACK)
return IUP_DEFAULT
end function
function canvas_unmap_cb(Ihandle canvas)
cdKillCanvas(cd_canvas)
return IUP_DEFAULT
end function
function canvas_resize_cb(Ihandle /*canvas*/)
integer {canvas_width, canvas_height} = IupGetIntInt(canvas, "DRAWSIZE")
atom res = IupGetDouble(NULL, "SCREENDPI")/25.4
cdCanvasSetAttribute(cd_canvas, "SIZE", "%dx%d %g", {canvas_width, canvas_height, res})
return IUP_DEFAULT
end function
function k_any(Ihandle /*ih*/, atom c)
if c=K_ESC then
return IUP_CLOSE
elsif c=K_UP then
for i=1 to 8 do
y[i] = y[i]+z[i]*Sx*S -- rotate vertices in Y-Z plane
z[i] = z[i]-y[i]*Sx*S
end for
elsif c=K_DOWN then
for i=1 to 8 do
y[i] = y[i]-z[i]*Sx*S -- rotate vertices in Y-Z plane
z[i] = z[i]+y[i]*Sx*S
end for
elsif c=K_LEFT then
for i=1 to 8 do
x[i] = x[i]+z[i]*Sy*S -- rotate vertices in X-Z plane
z[i] = z[i]-x[i]*Sy*S
end for
elsif c=K_RIGHT then
for i=1 to 8 do
x[i] = x[i]-z[i]*Sy*S -- rotate vertices in X-Z plane
z[i] = z[i]+x[i]*Sy*S
end for
elsif c='+' then
Size += 5
elsif c='-' then
Size = max(10,Size-5)
elsif c=' ' then
IupSetInt(hTimer,"RUN",not IupGetInt(hTimer,"RUN"))
end if
IupRedraw(canvas)
return IUP_CONTINUE
end function
function timer_cb(Ihandle /*ih*/)
for i=1 to 8 do
x[i] = x[i]+y[i]*Sz*S -- rotate vertices in X-Y plane
y[i] = y[i]-x[i]*Sz*S
y[i] = y[i]+z[i]*Sx*S -- rotate vertices in Y-Z plane
z[i] = z[i]-y[i]*Sx*S
x[i] = x[i]+z[i]*Sy*S -- rotate vertices in X-Z plane
z[i] = z[i]-x[i]*Sy*S
end for
IupUpdate(canvas)
return IUP_IGNORE
end function
procedure main()
IupOpen()
IupImageLibOpen()
canvas = IupGLCanvas()
IupSetAttribute(canvas, "RASTERSIZE", "640x480")
IupSetCallback(canvas, "ACTION", Icallback("canvas_action_cb"))
IupSetCallback(canvas, "MAP_CB", Icallback("canvas_map_cb"))
IupSetCallback(canvas, "UNMAP_CB", Icallback("canvas_unmap_cb"))
IupSetCallback(canvas, "RESIZE_CB", Icallback("canvas_resize_cb"))
dlg = IupDialog(IupVbox({canvas}))
IupSetAttribute(dlg, "TITLE", "Draw Cuboid")
IupSetCallback(dlg, "K_ANY", Icallback("k_any"))
IupShow(dlg)
IupSetAttribute(canvas, "RASTERSIZE", NULL)
hTimer = IupTimer(Icallback("timer_cb"), 40)
IupMainLoop()
IupClose()
end procedure
main()

View file

@ -1,19 +0,0 @@
3 elements d h w
: spaces ( n- ) &space times ;
: --- ( - ) '+ putc @w 2 * [ '- putc ] times '+ putc ;
: ? ( n- ) @h <> [ '| ] [ '+ ] if ;
: slice ( n- ) '/ putc @w 2 * spaces '/ putc @d swap - dup spaces ? putc cr ;
: |...|/ ( - ) @h [ '| putc @w 2 * spaces '| putc 1- spaces '/ putc cr ] iterd ;
: face ( - )
--- @w 1+ spaces '/ putc cr
|...|/
--- cr ;
: cuboid ( whd- )
!d !h !w cr
@d 1+ spaces --- cr
@d [ dup spaces slice ] iterd
face ;
2 3 4 cuboid

View file

@ -1,10 +0,0 @@
+----+
/ /|
/ / |
/ / |
/ / +
+----+ /
| | /
| | /
| |/
+----+

View file

@ -1,31 +1,31 @@
var DIR = Hash.new("-" => [1,0], "|" => [0,1], "/" => [1,1]);
const dirs = Hash("-" => [1,0], "|" => [0,1], "/" => [1,1])
 
func cuboid(nx, ny, nz) {
say("cuboid %d %d %d:" % [nx, ny, nz]);
var(x, y, z) = (8*nx, 2*ny, 4*nz);
var area = [];
say("cuboid %d %d %d:" % [nx, ny, nz])
var(x, y, z) = (8*nx, 2*ny, 4*nz)
var area = []
var line = func(n, sx, sy, c) {
var(dx, dy) = DIR{c}...;
0..n -> each {|i|
var (xi, yi) = (sx + i*dx, sy + i*dy);
area[yi] \\= [" "]*(x+y+1);
area[yi][xi] = (area[yi][xi] == " " ? c : '+');
};
};
0 .. nz-1 -> each {|i| line.call(x, 0, 4*i, "-")};
0 .. ny -> each {|i| line.call(x, 2*i, z + 2*i, "-")};
0 .. nx-1 -> each {|i| line.call(z, 8*i, 0, "|")};
0 .. ny -> each {|i| line.call(z, x + 2*i, 2*i, "|")};
0 .. nz-1 -> each {|i| line.call(y, x, 4*i, "/")};
0 .. nx -> each {|i| line.call(y, 8*i, z, "/")};
var(dx, dy) = dirs{c}...
for i (0..n) {
var (xi, yi) = (sx + i*dx, sy + i*dy)
area[yi] \\= [" "]*(x+y+1)
area[yi][xi] = (area[yi][xi] == " " ? c : '+')
}
}
 
0 .. nz-1 -> each {|i| line(x, 0, 4*i, "-") }
0 .. ny -> each {|i| line(x, 2*i, z + 2*i, "-") }
0 .. nx-1 -> each {|i| line(z, 8*i, 0, "|") }
0 .. ny -> each {|i| line(z, x + 2*i, 2*i, "|") }
0 .. nz-1 -> each {|i| line(y, x, 4*i, "/") }
0 .. nx -> each {|i| line(y, 8*i, z, "/") }
 
area.reverse.each { |line|
say line.join('');
};
say line.join('')
}
}
cuboid(2, 3, 4);
cuboid(1, 1, 1);
cuboid(6, 2, 1);
cuboid(2, 4, 1);
 
cuboid(2, 3, 4)
cuboid(1, 1, 1)
cuboid(6, 2, 1)
cuboid(2, 4, 1)

View file

@ -1,30 +1,30 @@
func cuboid (x=1,y=1,z=1,s=' ',c='+',h='-',v='|',d='/') {
say("cuboid %d %d %d:" % (x, y, z));
' ' * z+1 + c + h*x + c -> say;
say("cuboid %d %d %d:" % (x, y, z))
' ' * z+1 + c + h*x + c -> say
{ |i|
' ' * (z - i + 1) + d + s*x + d +
(s * (i - (i > y ? i-y : 1))) +
(i - 1 == y ? c : (i > y ? d : v)) -> say
} * z;
(s * (i - (i > y ? i-y : 1))) +
(i - 1 == y ? c : (i > y ? d : v)) -> say
}.for(1..z)
c + h*x + c + (s * (z < y ? z : y) +
(z < y ? v : (z == y ? c : d))) -> say;
c + h*x + c + (s * (z < y ? z : y) +
(z < y ? v : (z == y ? c : d))) -> say
{ |i|
v + s*x + v + (z > y
? (i >= z ? (s*x + c) : (s * y-i + d))
: (y - i > z
? (s * z + v)
: (s * y-i + (y-i == z ? c : d))
 ? (i >= z ? (s*x + c) : (s * y-i + d))
 : (y - i > z
 ? (s * z + v)
 : (s * y-i + (y-i == z ? c : d))
)
) -> say;
} * y;
}.for(1..y)
c + h*x + c -> say;
};
c + h*x + c -> say
}
cuboid(2, 3, 4);
cuboid(1, 1, 1);
cuboid(6, 2, 1);
cuboid(2, 4, 1);
cuboid(2, 3, 4)
cuboid(1, 1, 1)
cuboid(6, 2, 1)
cuboid(2, 4, 1)

View file

@ -0,0 +1,21 @@
var [const] M=50.0;
fcn cuboid(w,h,z){
w*=M; h*=M; z*=M; // relative to abs dimensions
bitmap:=PPM(400,400);
clr:=0xff0000; // red facing rectangle
bitmap.line(0,0, w,0, clr); bitmap.line(0,0, 0,h, clr);
bitmap.line(0,h, w,h, clr); bitmap.line(w,0, w,h, clr);
r,a:=(w+z).toFloat().toPolar(0); // relative to the origin
a,b:=r.toRectangular((30.0).toRad() + a).apply("toInt"); c:=a; d:=b+h;
clr=0xff; // blue right side of cuboid
bitmap.line(w,0, a,b, clr); bitmap.line(a,b, c,d, clr);
bitmap.line(w,h, c,d, clr);
e:=c-w;
clr=0xfff00; // green top of cuboid
bitmap.line(0,h, e,d, clr); bitmap.line(c,d, e,d, clr);
bitmap.write(File("foo.ppm","wb"));
}(2,3,4);