Draw a cuboid: Difference between revisions

Added PL/M
(Added PL/M)
 
(10 intermediate revisions by 6 users not shown)
Line 203:
| |/
+----+ </pre>
 
=={{header|ALGOL 68}}==
Draws a static cuboid using ASCII art - orientated in the same fashion as in the Befunge sample.<br/>
(I'm not au-fait with Befunge, so I've no idea how similar the algorithm is...)
<syntaxhighlight lang="algol68">
BEGIN # draw some cuboids using ASCII art #
 
# draws a cuboid standing on one edge using ASCII art #
PROC aa cuboid = ( INT h, w, l )VOID:
BEGIN
# top line #
FOR i TO l DO print( ( " " ) ) OD;
FOR i TO w + 1 DO print( ( "_" ) ) OD;
print( ( newline ) );
# rest of the top face and part of the visible side #
INT face width := 0;
INT edge pos := 0;
FOR i TO l DO
FOR j TO l - i DO print( ( " " ) ) OD;
print( ( "/" ) );
FOR j TO w DO print( ( IF i = l THEN "_" ELSE " " FI ) ) OD;
print( ( "/" ) );
edge pos +:= 1;
IF edge pos <= h THEN
# drsw the back edge #
face width := 2 * ( edge pos - 1 );
FOR j TO face width DO print( ( " " ) ) OD;
print( ( "\" ) )
ELSE
# draw the bottom edge #
FOR j TO face width + 1 DO print( ( " " ) ) OD;
print( ( "/" ) )
FI;
print( ( newline ) )
OD;
# other vidible face #
FOR i TO h DO
FOR j TO i - 1 DO print( ( " " ) ) OD;
print( ( "\" ) );
FOR j TO w DO print( ( IF i = h THEN "_" ELSE " " FI ) ) OD;
print( ( "\" ) );
edge pos +:= 1;
IF edge pos <= h THEN
# drsw the back edge #
FOR j TO face width + 1 DO print( ( " " ) ) OD;
print( ( "\" ) )
ELSE
# draw the bottom edge #
FOR j TO face width DO print( ( " " ) ) OD;
face width -:= 2;
print( ( "/" ) )
FI;
print( ( newline ) )
OD
END # aa cuboid # ;
 
aa cuboid( 3, 2, 4 );
aa cuboid( 4, 3, 2 );
aa cuboid( 2, 4, 3 );
aa cuboid( 2, 3, 4 )
 
END
</syntaxhighlight>
{{out}}
<pre>
___
/ /\
/ / \
/ / \
/__/ /
\ \ /
\ \ /
\__\/
____
/ /\
/___/ \
\ \ \
\ \ \
\ \ /
\___\/
_____
/ /\
/ / \
/____/ /
\ \ /
\____\/
____
/ /\
/ / \
/ / /
/___/ /
\ \ /
\___\/
</pre>
 
=={{header|Arturo}}==
Line 943 ⟶ 1,038:
readln;
end.</syntaxhighlight>
 
=={{header|EasyLang}}==
[https://easylang.online/show/#cod=jZRNj9owEIbv/hWv2BsoEUkIUKk5rNRjT5V6inKgxFALsFdJVGJ+fTX+2Dhp2C5CTBg/8854PI5UNS+rskKBEiWiBFFK3+r9T+KfQ793h3hAB7BnK8brc5iKFghIsTF2g8zYzGnk2Bq7xd7YPXbG7pA74dzFb13czunsTboXsLdGHdEeD1eOE2LEDMBJNRAokKBTuHIJ6TpAi2699uuZcwIWE1VZV1gWOLkFIxmz2KZqVHfoOA7y3NOP9jlbIXsUZMwauY6qJddRte+uVkg9UNpReqD0Z+onVV9r4p2PwJl550ChQI+lrSnCA0tTscN0EJuGgg8fsjLRQciAo4C2mB6U9QTLqkFNY2UiPEa9NbusywqZbXPdHO6+tccrPzT0cFN/OFKk9NzxvsPitWnUHReuW2qVPZuFQVHgC33MH2pmlHymteIUlvwVt2E6bnMN9upiPCykRKc0n9PfkiGn8fhzuolgJOtS9OT0RBpkFj1WLgcAfg2E0v8KJU+Fhj1Q5XLcrnp0iz7a1szOZF1KUUE14zqtewijEU98tweBcc00trNQOlFKp1A6ozQLTZTM+PUJVsjXlJvsCLgKySmfBdIJEE/fJzTCrXhwZMy+wJKcudfLJscmZ3QJmJI038x288L1rwun62pH/+fbwqm6wLU9RTMLU/ibust/8Og5/52fugkfJVg/5X+I8+9pgOPNns12Ysb+Ag== Run it]
<syntaxhighlight>
node[][] = [ [ -1 -2 -2 ] [ -1 -2 1 ] [ -1 2 -2 ] [ -1 2 1 ] [ 1 -2 -2 ] [ 1 -2 1 ] [ 1 2 -2 ] [ 1 2 1 ] ]
edge[][] = [ [ 1 2 ] [ 2 4 ] [ 4 3 ] [ 3 1 ] [ 5 6 ] [ 6 8 ] [ 8 7 ] [ 7 5 ] [ 1 5 ] [ 2 6 ] [ 3 7 ] [ 4 8 ] ]
#
proc scale f . .
for i = 1 to len node[][]
for d = 1 to 3
node[i][d] *= f
.
.
.
proc rotate angx angy . .
sinx = sin angx
cosx = cos angx
siny = sin angy
cosy = cos angy
for i = 1 to len node[][]
x = node[i][1]
z = node[i][3]
node[i][1] = x * cosx - z * sinx
y = node[i][2]
z = z * cosx + x * sinx
node[i][2] = y * cosy - z * siny
node[i][3] = z * cosy + y * siny
.
.
len nd[] 3
proc draw . .
clear
move 2 2
text "Arrow keys to rotate"
m = 99999
mi = -1
for i = 1 to len node[][]
if node[i][3] < m
m = node[i][3]
mi = i
.
.
ix = 1
for i = 1 to len edge[][]
if edge[i][1] = mi
nd[ix] = edge[i][2]
ix += 1
elif edge[i][2] = mi
nd[ix] = edge[i][1]
ix += 1
.
.
for ni = 1 to len nd[]
for i = 1 to len edge[][]
if edge[i][1] = nd[ni] or edge[i][2] = nd[ni]
x1 = node[edge[i][1]][1]
y1 = node[edge[i][1]][2]
x2 = node[edge[i][2]][1]
y2 = node[edge[i][2]][2]
move x1 + 50 y1 + 50
line x2 + 50 y2 + 50
.
.
.
.
textsize 3
scale 15
rotate 45 45
draw
on key
if keybkey = "ArrowUp"
rotate 0 1
elif keybkey = "ArrowDown"
rotate 0 -1
elif keybkey = "ArrowLeft"
rotate -1 0
elif keybkey = "ArrowRight"
rotate 1 0
.
draw
.
</syntaxhighlight>
 
=={{header|Elixir}}==
Line 1,036 ⟶ 1,213:
+-----+-----+-----+-----+
</pre>
 
=={{header|Evaldraw}}==
 
=== Solid and stippled lines ===
{{trans|XPL0}}
 
Based on the XPL0 solution, but provides its own stippled line drawing routine, since evaldraw only supports solid lines out of the box.
 
[[File:Evaldraw line cuboid.gif|thumb|alt=Rotating cuboid drawn with solid visible lines and stippled hidden lines|Rotating cuboid. Visible lines solid, hidden edges drawn with stippled lines]]
 
<syntaxhighlight lang="C">
static points_x[8] = {-2.0, +2.0, +2.0, -2.0, -2.0, +2.0, +2.0, -2.0};
static points_y[8] = {-1.5, -1.5, +1.5, +1.5, -1.5, -1.5, +1.5, +1.5};
static points_z[8] = {-1.0, -1.0, -1.0, -1.0, +1.0, +1.0, +1.0, +1.0};
static segment[2*12] = {0,1, 1,2, 2,3, 3,0, 4,5, 5,6, 6,7, 7,4, 0,4, 1,5, 2,6, 3,7};
static size=50, sz=0.008, sx=-0.013; // drawing size and tumbling speeds
() {
mind = 0.0; si=0;
for(i=0; i<8; i++) {
if (points_z[i] < mind) { mind=points_z[i]; si=i;}
}
cls(0); // Clear Color Buffer
for(i=0; i<2*12-1; i+=2) {
j=segment[i];
x0 = points_x[j]*size + xres/2;
y0 = points_y[j]*size + yres/2;
k=segment[i+1];
x1 = points_x[k]*size + xres/2;
y1 = points_y[k]*size + yres/2;
if (j!=si && k!=si) {
setcol(255,0,0);
moveto(x0,y0); lineto(x1,y1);
} else {
setcol(255,255,0);
drawLineStipple(x0,y0,x1,y1,8);
}
}
sleep(16); // Sleep for 16 millis so cube tumbles slowly
for(i=0; i<8; i++) {
points_x[i] = points_x[i] + points_y[i]*Sz; //rotate vertices in X-Y plane
points_y[i] = points_y[i] - points_x[i]*Sz;
points_y[i] = points_y[i] + points_z[i]*Sx; //rotate vertices in Y-Z plane
points_z[i] = points_z[i] - points_y[i]*Sx;
}
}
 
drawLineStipple(x1,y1,x2,y2,stipple_dist) {
xdist = x1-x2; ydist=y1-y2;
stipple_dist2 = stipple_dist / 2;
if ( abs(xdist^2 + ydist^2) < stipple_dist2^2 ) return;
if(xdist < 0) xdist=-xdist;
if(ydist < 0) ydist=-ydist;
mv=0; if(ydist > xdist) mv = ydist; else mv = xdist;
x = x1; y = y1;
stepx = xdist/mv; if(x1 > x2) stepx = -stepx;
stepy = ydist/mv; if(y1 > y2) stepy = -stepy;
for(nc=0; nc<int(mv); nc++) {
if( nc % stipple_dist < stipple_dist2) setpix(x,y);
x+=stepx; y+=stepy;
}
}
</syntaxhighlight>
 
=== OpenGL-like filled polygons ===
 
[[File:Evaldraw textured cuboid.png|thumb|alt=Cuboid, 2 units wide, 3 units high, 4 units deep|Textured cuboid. Each face has its own color. Rotate with mouse position.]]
 
<syntaxhighlight lang="C">// We can define our own vec3 struct
struct vec3{x,y,z;}
 
// Static allows for globals
static modelMatrix[9];
() {
cls(0,0,32); // clear screen
clz(1e32); // clear depth buffer
setcam(0,0,-10,0,0); // set camera some units back
// create two local arrays to hold rotation matrices
double roty[9], rotz[9];
// we can access current mouse position and screen size
rotateZ( rotz, mousy/yres*2*pi );
rotateY( roty, mousx/xres*2*pi );
// evaldraw does support some GL-like drawing
// modes, but any transformations must be done by hand
// Here we use a global model matrix that
// transforms vertices created by the myVertex function
mult(modelMatrix, roty, rotz);
drawcuboid(0,0,0,2,3,4);
sleep(10);
}
 
drawcuboid(x,y,z,sx,sy,sz) {
glBegin(GL_QUADS);
setcol(192,0,0);
glTexCoord(0,0); myVertex(x-sx,y-sy,z-sz);
glTexCoord(1,0); myVertex(x+sx,y-sy,z-sz);
glTexCoord(1,1); myVertex(x+sx,y+sy,z-sz);
glTexCoord(0,1); myVertex(x-sx,y+sy,z-sz);
setcol(0,192,0);
glTexCoord(0,0); myVertex(x-sx,y-sy,z+sz);
glTexCoord(1,0); myVertex(x-sx,y-sy,z-sz);
glTexCoord(1,1); myVertex(x-sx,y+sy,z-sz);
glTexCoord(0,1); myVertex(x-sx,y+sy,z+sz);
setcol(0,0,192);
glTexCoord(0,0); myVertex(x+sx,y-sy,z+sz);
glTexCoord(1,0); myVertex(x-sx,y-sy,z+sz);
glTexCoord(1,1); myVertex(x-sx,y+sy,z+sz);
glTexCoord(0,1); myVertex(x+sx,y+sy,z+sz);
setcol(192,192,0);
glTexCoord(0,0); myVertex(x+sx,y-sy,z-sz);
glTexCoord(1,0); myVertex(x+sx,y-sy,z+sz);
glTexCoord(1,1); myVertex(x+sx,y+sy,z+sz);
glTexCoord(0,1); myVertex(x+sx,y+sy,z-sz);
 
setcol(192,0,192);
glTexCoord(0,0); myVertex(x-sx,y-sy,z+sz);
glTexCoord(1,0); myVertex(x+sx,y-sy,z+sz);
glTexCoord(1,1); myVertex(x+sx,y-sy,z-sz);
glTexCoord(0,1); myVertex(x-sx,y-sy,z-sz);
 
setcol(0,192,192);
glTexCoord(0,0); myVertex(x-sx,y+sy,z-sz);
glTexCoord(1,0); myVertex(x+sx,y+sy,z-sz);
glTexCoord(1,1); myVertex(x+sx,y+sy,z+sz);
glTexCoord(0,1); myVertex(x-sx,y+sy,z+sz);
glEnd();
}
 
myVertex(x,y,z) {
// Initialize a struct value
vec3 v = {x,y,z};
// Apply global model matrix transformation
transformPoint(v, modelMatrix);
// Submit the vertex to draw list
glVertex(v.x, v.y, v.z);
}
 
rotateX(m[9], r) { // structs and arrays are pass-by-ref
c = cos(r); s=sin(r);
m[0] = 1; m[1] = 0; m[2] = 0;
m[3] = 0; m[4] = c; m[5] = -s;
m[6] = 0; m[7] = s; m[8] = c;
}
 
rotateY(m[9], r) {
c = cos(r); s=sin(r);
m[0] = c; m[1] = 0; m[2] = s;
m[3] = 0; m[4] = 1; m[5] = 0;
m[6] = -s; m[7] = 0; m[8] = c;
}
 
rotateZ(m[9], r) {
c = cos(r); s=sin(r);
m[0] = c; m[1] = -s; m[2] = 0;
m[3] = s; m[4] = c; m[5] = 0;
m[6] = 0; m[7] = 0; m[8] = 1;
}
 
transformPoint(vec3 v, m[9]) {
x2 = v.x * m[0] + v.y * m[1] + v.z * m[2];
y2 = v.x * m[3] + v.y * m[4] + v.z * m[5];
z2 = v.x * m[6] + v.y * m[7] + v.z * m[8];
// Mutate the struct v with new values
v.x=x2; v.y=y2; v.z=z2;
}
 
mult(c[9],a[9],b[9]) { // C = AB
// multiply a row in A with a column in B
for(i=0; i<3; i++)
for(j=0; j<3; j++) {
sum = 0.0;
for(k=0; k<3; k++) {
sum += A[k*3+i] * B[k*3+j];
}
C[i*3+j] = sum;
}
}</syntaxhighlight>
 
=={{header|Factor}}==
Line 1,736 ⟶ 2,102:
</body>
</html></syntaxhighlight>
 
=={{header|jq}}==
'''Adapted from [[#Wren|Wren]]'''
 
'''Works with jq, the C implementation of jq'''
 
'''Works with gojq, the Go implementation of jq'''
 
'''Works with jaq, the Rust implementation of jq'''
 
The following has been written so as to produce identical results
using any of these three implementations of jq.
<syntaxhighlight lang="jq">
def cubLine($n; $dx; $dy; $cde):
def s: if . == 0 then "" else . * " " end; # for jaq
reduce range(1; 9*$dx) as $d ("\($n|s)\($cde[0:1])";
. + $cde[1:2] )
+ $cde[0:1]
+ ("\($dy|s)\($cde[2:])");
 
def cuboid($dx; $dy; $dz):
"cuboid \($dx) \($dy) \($dz):",
# top
cubLine($dy+1; $dx; 0; "+-"),
# top and side
(range(1; 1+$dy) as $i | cubLine($dy-$i+1; $dx; $i-1; "/ |")),
cubLine(0; $dx; $dy; "+-|"),
# front and side
(range(1; 4*$dz -$dy-2) as $i | cubLine(0; $dx; $dy; "| |")),
cubLine(0; $dx; $dy; "| +"),
# front and bottom
(range(1; 1+$dy) as $i | cubLine(0; $dx; $dy-$i; "| /")),
# bottom
cubLine(0; $dx; 0; "+-\n");
 
cuboid(2; 3; 4),
"",
cuboid(1; 1; 1),
"",
cuboid(6; 2; 1)
</syntaxhighlight>
{{output}}
<pre>
cuboid 2 3 4:
+-----------------+
/ /|
/ / |
/ / |
+-----------------+ |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | +
| | /
| | /
| |/
+-----------------+
 
 
cuboid 1 1 1:
+--------+
/ /|
+--------+ |
| | +
| |/
+--------+
 
 
cuboid 6 2 1:
+-----------------------------------------------------+
/ /|
/ / |
+-----------------------------------------------------+ |
| | +
| | /
| |/
+-----------------------------------------------------+
</pre>
 
=={{header|Julia}}==
Line 3,075 ⟶ 3,526:
 
(glutMainLoop)</syntaxhighlight>
 
=={{header|PL/M}}==
{{works with|8080 PL/M Compiler}} ... under CP/M (or an emulator)
{{Trans|ALGOL 68}}
<syntaxhighlight lang="plm">
100H: /* DRAW SOME CUBOIDS USING ASCII ART */
 
/* CP/M BDOS SYSTEM CALL AND I/O ROUTINES */
BDOS: PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5; END;
PR$CHAR: PROCEDURE( C ); DECLARE C BYTE; CALL BDOS( 2, C ); END;
PR$NL: PROCEDURE; CALL PR$CHAR( 0DH ); CALL PR$CHAR( 0AH ); END;
 
/* TASK */
 
/* DRAWS A CUBOID STANDING ON ONE EDGE USING ASCII ART */
DRAW$CUBOID: PROCEDURE( H, W, L );
DECLARE ( H, W, L ) BYTE;
DECLARE ( I, J, FACE$WIDTH, EDGE$POS ) BYTE;
 
BACKSLASH: PROCEDURE; CALL PR$CHAR( 92 ); END; /* PRINTS A BACKSLASH */
REPEAT$CHAR: PROCEDURE( CH, COUNT ); /* PRINTS CH COUNT TIMES */
DECLARE ( CH, COUNT ) BYTE;
DECLARE I BYTE;
IF COUNT > 0 THEN DO;
DO I = 1 TO COUNT; CALL PR$CHAR( CH ); END;
END;
END REPEAT$CHAR;
UNDERSCORES: PROCEDURE( COUNT ); /* PRINTS COUNT UNDERSCORES */
DECLARE COUNT BYTE;
CALL REPEAT$CHAR( 95, COUNT );
END UNDERSCORES;
 
/* TOP LINE */
CALL REPEAT$CHAR( ' ', L ); CALL UNDERSCORES( W + 1 ); CALL PR$NL;
/* REST OF THE TOP FACE AND PART OF THE VISIBLE SIDE */
FACE$WIDTH = 0;
EDGE$POS = 0;
DO I = 1 TO L;
CALL REPEAT$CHAR( ' ', L - I );
CALL PR$CHAR( '/' );
IF I = L THEN CALL UNDERSCORES( W );
ELSE CALL REPEAT$CHAR( ' ', W );
CALL PR$CHAR( '/' );
EDGE$POS = EDGE$POS + 1;
IF EDGE$POS <= H THEN DO;
/* DRAW THE BACK EDGE */
FACE$WIDTH = 2 * ( EDGE$POS - 1 );
CALL REPEAT$CHAR( ' ', FACE$WIDTH );
CALL BACKSLASH;
END;
ELSE DO;
/* DRAW THE BOTTOM EDGE AND THE MORE OF THE VISIBLE SIDE */
CALL REPEAT$CHAR( ' ', FACE$WIDTH + 1 );
CALL PR$CHAR( '/' );
END;
CALL PR$NL;
END;
/* OTHER VISIBLE FACE */
DO I = 1 TO H;
CALL REPEAT$CHAR( ' ', I - 1 );
CALL BACKSLASH;
IF I = H THEN CALL UNDERSCORES( W );
ELSE CALL REPEAT$CHAR( ' ', W );
CALL BACKSLASH;
EDGE$POS = EDGE$POS + 1;
IF EDGE$POS <= H THEN DO;
/* DRAW THE BACK EDGE */
CALL REPEAT$CHAR( ' ', FACE$WIDTH + 1 );
CALL BACKSLASH;
END;
ELSE DO;
/* DRAW THE BOTTOM EDGE */
CALL REPEAT$CHAR( ' ', FACE$WIDTH );
FACE$WIDTH = FACE$WIDTH - 2;
CALL PR$CHAR( '/' );
END;
CALL PR$NL;
END;
END DRAW$CUBOID;
 
CALL DRAW$CUBOID( 3, 2, 4 );
CALL DRAW$CUBOID( 4, 3, 2 );
CALL DRAW$CUBOID( 2, 4, 3 );
CALL DRAW$CUBOID( 2, 3, 4 );
 
EOF
</syntaxhighlight>
{{out}}
<pre>
___
/ /\
/ / \
/ / \
/__/ /
\ \ /
\ \ /
\__\/
____
/ /\
/___/ \
\ \ \
\ \ \
\ \ /
\___\/
_____
/ /\
/ / \
/____/ /
\ \ /
\____\/
____
/ /\
/ / \
/ / /
/___/ /
\ \ /
\___\/
</pre>
 
=={{header|POV-Ray}}==
<syntaxhighlight lang="pov-ray">camera { perspective location <2.6,2.2,-4.2> look_at <0,-.5,0>
aperture .05 blur_samples 100 variance 1/100000 focal_point <2,1,-2>}
Line 4,409 ⟶ 4,978:
{{trans|Go}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="ecmascriptwren">import "./fmt" for Fmt
 
var cubLine = Fn.new { |n, dx, dy, cde|
3,049

edits