Draw a cuboid
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
The task is to draw a cuboid with relative dimensions of 2x3x4. The cuboid can be represented graphically, or in ascii art, depending on the language capabilities. To fulfil the criteria of being a cuboid, three faces must be visible. Either static or rotational projection is acceptable for this task.
Ada
ASCII-Art output, one width unit is two characters long ('--'). <lang Ada>with Ada.Text_IO;
procedure Main is
type Char_Matrix is array (Positive range <>, Positive range <>) of Character;
function Create_Cuboid (Width, Height, Depth : Positive) return Char_Matrix is Result : Char_Matrix (1 .. Height + Depth + 3, 1 .. 2 * Width + Depth + 3) := (others => (others => ' ')); begin -- points Result (1, 1) := '+'; Result (Height + 2, 1) := '+'; Result (1, 2 * Width + 2) := '+'; Result (Height + 2, 2 * Width + 2) := '+'; Result (Height + Depth + 3, Depth + 2) := '+'; Result (Depth + 2, 2 * Width + Depth + 3) := '+'; Result (Height + Depth + 3, 2 * Width + Depth + 3) := '+'; -- width lines for I in 1 .. 2 * Width loop Result (1, I + 1) := '-'; Result (Height + 2, I + 1) := '-'; Result (Height + Depth + 3, Depth + I + 2) := '-'; end loop; -- height lines for I in 1 .. Height loop Result (I + 1, 1) := '|'; Result (I + 1, 2 * Width + 2) := '|'; Result (Depth + I + 2, 2 * Width + Depth + 3) := '|'; end loop; -- depth lines for I in 1 .. Depth loop Result (Height + 2 + I, 1 + I) := '/'; Result (1 + I, 2 * Width + 2 + I) := '/'; Result (Height + 2 + I, 2 * Width + 2 + I) := '/'; end loop; return Result; end Create_Cuboid;
procedure Print_Cuboid (Width, Height, Depth : Positive) is Cuboid : Char_Matrix := Create_Cuboid (Width, Height, Depth); begin for Row in reverse Cuboid'Range (1) loop for Col in Cuboid'Range (2) loop Ada.Text_IO.Put (Cuboid (Row, Col)); end loop; Ada.Text_IO.New_Line; end loop; end Print_Cuboid;
begin
Print_Cuboid (2, 3, 4);
end Main;</lang>
output:
+----+ / /| / / | / / | / / + +----+ / | | / | | / | |/ +----+
Brlcad
In brlcad, we use the rpp (rectangular parallelepiped) primitive to create the cuboid. This defines the cuboid area using the parameters xmin,xmax,ymin,ymax,zmin,zmax
<lang brlcad>opendb cuboid.g y # Create a database to hold our shapes units cm # Set the unit of measure in cuboid.s rpp 0 2 0 3 0 4 # Create a 2 x 3 x 4 cuboid named cuboid.s</lang>
Logo
In Logo, we can use the perspective function to make drawing 3D-objects easier.
(MSWlogo can be downloaded here ([1]), available for all major versions of Windows.
Simple implementation, just moving to the appropriate points every time.
<lang logo>to cuboid :l1 :l2 :l3
cs perspective ;making the room ready to use
setxyz :l1 0 0
setxyz :l1 :l2 0
setxyz 0 :l2 0
setxyz 0 0 0
setxyz :l1 0 0
setxyz :l1 0 -:l3
setxyz :l1 :l2 -:l3
setxyz :l1 :l2 0
setxyz 0 :l2 0
setxyz 0 :l2 -:l3
setxyz :l1 :l2 -:l3
end</lang>
Example call to achieve task:
<lang logo>cuboid 50 100 150</lang>
Mathematica
This creates a cuboid with one corner at (0,0,0) and the opposite at (2,3,4): <lang Mathematica>Graphics3D[Cuboid[{0,0,0},{2,3,4}]]</lang> Output would be fully-rendered, rotatable 3D in the notebook. Also, many aspects of the cuboid's appearance and lighting can be controlled quite easily. For those, see Mathematica's documentation in the program or on the web.
Openscad
Drawing a cuboid is easy in openscad:
<lang openscad>// This will produce a simple cuboid cube([2,3,4])</lang>
PicoLisp
Using ASCII
<lang PicoLisp>(de cuboid (DX DY DZ)
(cubLine (inc DY) "+" DX "-" 0) (for I DY (cubLine (- DY I -1) "/" DX " " (dec I) "|") ) (cubLine 0 "+" DX "-" DY "|") (do (- (* 4 DZ) DY 2) (cubLine 0 "|" DX " " DY "|") ) (cubLine 0 "|" DX " " DY "+") (for I DY (cubLine 0 "|" DX " " (- DY I) "/") ) (cubLine 0 "+" DX "-" 0) )
(de cubLine (N C DX D DY E)
(space N) (prin C) (do (dec (* 9 DX)) (prin D)) (prin C) (space DY) (prinl E) )</lang>
Output:
: (cuboid 2 3 4) +-----------------+ / /| / / | / / | +-----------------+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | / | | / | |/ +-----------------+ : (cuboid 1 1 1) +--------+ / /| +--------+ | | | | | | + | |/ +--------+ : (cuboid 6 2 1) +-----------------------------------------------------+ / /| / / | +-----------------------------------------------------+ | | | + | | / | |/ +-----------------------------------------------------+
Using OpenGL
<lang PicoLisp>(load "@lib/openGl.l")
(setq *AngleX -26.0 *AngleY 74.0) (setq *LastX 0 *LastY 0)
(glutInit) (glutInitDisplayMode (| GLUT_RGBA GLUT_DOUBLE GLUT_DEPTH)) (glutInitWindowSize 512 512) (glutInitWindowPosition 10 50) (glutCreateWindow "PicoLisp Cube")
(glClearColor 1.0 1.0 1.0 1.0) # The background color (glEnable GL_DEPTH_TEST) (glEnable GL_LIGHTING) (glEnable GL_LIGHT0) (glDisable GL_CULL_FACE)
(glEnable GL_BLEND) (glBlendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA) (glEnable GL_LINE_SMOOTH) (glHint GL_LINE_SMOOTH_HINT GL_NICEST) (glLineWidth 2.0)
(mouseFunc
'((Btn State X Y) (setq *LastX X *LastY Y) ) )
(motionFunc
'((X Y) (inc '*AngleX (* (- Y *LastY) 1.0)) (inc '*AngleY (* (- X *LastX) 1.0)) (setq *LastX X *LastY Y) (glutPostRedisplay) ) )
(reshapeFunc
'((Width Height) (glMatrixMode GL_PROJECTION) (glLoadIdentity) (gluPerspective 45.0 (*/ Width 1.0 Height) 1.0 10.0) (glMatrixMode GL_MODELVIEW) (glViewport 0 0 Width Height) ) )
(displayPrg (glClear (| GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT)) (glLoadIdentity) (glTranslatef 0.0 0.0 -3.0) (glRotatef *AngleX 1 0 0) (glRotatef *AngleY 0 1 0) (glutSolidCube 1.0)
(glDisable GL_LIGHTING) (glColor4f 0.4 0.4 0.4 1.0) (glutWireCube 1.002) (glEnable GL_LIGHTING)
(glFlush) (glutSwapBuffers) )
(glutMainLoop)</lang>
POV-Ray
<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>}
light_source{< 60,20,-20> color rgb 2}
sky_sphere { pigment{ gradient z color_map{[0 rgb 0.3][.1 rgb <.7,.8,1>][1 rgb .2]} }}
box { <0,0,0> <3,2,4>
texture { pigment{ agate } normal { checker } finish { reflection {0.20 metallic 0.2} } } translate <-1,-.5,-2>
} </lang>
Prolog
Works with SWI-Prolog and XPCE. <lang Prolog>cuboid(D1,D2,D3) :- W is D1 * 50, H is D2 * 50, D is D3 * 50,
new(C, window(cuboid)),
% compute the size of the window Width is W + ceiling(sqrt(H * 48)) + 50, Height is H + ceiling(sqrt(H * 48)) + 50, send(C, size, new(_,size(Width,Height))),
%compute the top-left corner of the front face of the cuboid PX is 25, PY is 25 + ceiling(sqrt(H * 48)),
% colors of the faces new(C1, colour(@default, 65535, 0, 0)), new(C2, colour(@default, 0, 65535, 0)), new(C3, colour(@default, 0, 0, 65535)),
% the front face new(B1, box(W, H)), send(B1, fill_pattern, C1), send(C, display,B1, point(PX, PY)),
% the top face new(B2, hpara(point(PX,PY), W, D, C2)), send(C, display, B2),
% the left face PX1 is PX + W, new(B3, vpara(point(PX1,PY), H, D, C3)), send(C, display, B3),
send(C, open).
- - pce_begin_class(hpara, path, "drawing of a horizontal parallelogram").
initialise(P, Pos, Width, Hight, Color) :-> send(P, send_super, initialise), send(P, append, Pos), H is ceiling(sqrt(Hight * 48)), get(Pos, x, X), get(Pos, y, Y), X1 is X + H, Y1 is Y - H, send(P, append, point(X1, Y1)), X2 is X1 + Width, send(P, append, point(X2, Y1)), X3 is X2 - H, send(P, append, point(X3, Pos?y)), send(P, append, Pos), send(P, fill_pattern, Color).
- - pce_end_class.
- - pce_begin_class(vpara, path, "drawing of a vertical parallelogram").
initialise(P, Pos, Hight, Depth, Color) :-> send(P, send_super, initialise), send(P, append, Pos), H is ceiling(sqrt(Depth * 48)), get(Pos, x, X), get(Pos, y, Y), X1 is X + H, Y1 is Y - H, send(P, append, point(X1, Y1)), Y2 is Y1 + Hight, send(P, append, point(X1, Y2)), Y3 is Y2 + H, send(P, append, point(X, Y3)), send(P, append, Pos), send(P, fill_pattern, Color).
- - pce_end_class.
</lang> Example of output :
?- cuboid(2,3,4). true.
Python
<lang python>def _pr(t, x, y, z):
txt = '\n'.join(.join(t[(n,m)] for n in range(3+x+z)).rstrip() for m in reversed(range(3+y+z))) return txt
def cuboid(x,y,z):
t = {(n,m):' ' for n in range(3+x+z) for m in range(3+y+z)} xrow = ['+'] + ['%i' % (i % 10) for i in range(x)] + ['+'] for i,ch in enumerate(xrow): t[(i,0)] = t[(i,1+y)] = t[(1+z+i,2+y+z)] = ch if _debug: print(_pr(t, x, y, z)) ycol = ['+'] + ['%i' % (j % 10) for j in range(y)] + ['+'] for j,ch in enumerate(ycol): t[(0,j)] = t[(x+1,j)] = t[(2+x+z,1+z+j)] = ch zdepth = ['+'] + ['%i' % (k % 10) for k in range(z)] + ['+'] if _debug: print(_pr(t, x, y, z)) for k,ch in enumerate(zdepth): t[(k,1+y+k)] = t[(1+x+k,1+y+k)] = t[(1+x+k,k)] = ch
return _pr(t, x, y, z)
_debug = False
if __name__ == '__main__':
for dim in ((2,3,4), (3,4,2), (4,2,3)): print("CUBOID%r" % (dim,), cuboid(*dim), sep='\n')</lang>
Output
CUBOID(2, 3, 4) +01+ 3 32 2 2 1 1 1 0 0 0 + +01+ 3 2 2 2 1 1 1 0 00 +01+ CUBOID(3, 4, 2) +012+ 1 13 0 0 2 +012+ 1 3 3 0 2 2 + 1 1 1 0 00 +012+ CUBOID(4, 2, 3) +0123+ 2 21 1 1 0 0 0 + +0123+ 2 1 1 1 0 00 +0123+
PureBasic
Using generic PureBasic 2D-library. <lang PureBasic>Procedure Draw_a_Cuboid(Window, X,Y,Z)
w=WindowWidth(Window) h=WindowHeight(Window) diag.f=1.9 If Not (w And h): ProcedureReturn: EndIf xscale.f = w/(x+z/diag)*0.98 yscale.f = h/(y+z/diag)*0.98 If xscale<yscale Scale.f = xscale Else Scale = yscale EndIf x*Scale: Y*Scale: Z*Scale CreateImage(0,w,h) If StartDrawing(ImageOutput(0)) c= RGB(250, 40, 5) ;- Calculate the cones in the Cuboid xk = w/50 : yk = h/50 x0 = Z/2 + xk : y0 = yk x1 = x0 + X : y1 = y0 x2 = xk : y2 = y0 + Z/2 x3 = x2 + X : y3 = y2 x4 = x2 : y4 = y2 + Y x5 = x4 + X : y5 = y4 x6 = x5 + Z/2 : y6 = y5 - Z/2 ;- Draw it LineXY(x0,y0,x1,y1,c) LineXY(x0,y0,x2,y2,c) LineXY(x2,y2,x3,y3,c) LineXY(x1,y1,x3,y3,c) LineXY(x2,y2,x4,y4,c) LineXY(x4,y4,x5,y5,c) LineXY(x5,y5,x4,y4,c) LineXY(x5,y5,x6,y6,c) LineXY(x5,y5,x3,y3,c) LineXY(x6,y6,x1,y1,c) ;- Fill the areas FillArea(x,y,-1,RGB(255, 0, 0)) FillArea(x,y-z/2,-1,RGB(0, 0, 255)) FillArea(x+z/2,y,-1,RGB(0, 255, 0)) StopDrawing() EndIf ;- Update the graphic ImageGadget(0,0,0,w,h,ImageID(0))
EndProcedure
- WFlags = #PB_Window_SystemMenu|#PB_Window_SizeGadget
- title = "PureBasic Cuboid"
MyWin = OpenWindow(#PB_Any, 0, 0, 200, 250, #title, #WFlags)
Repeat
WEvent = WaitWindowEvent() If WEvent = #PB_Event_SizeWindow Draw_a_Cuboid(MyWin, 2, 3, 4) EndIf
Until WEvent = #PB_Event_CloseWindow
- - Save the image?
UsePNGImageEncoder() respons = MessageRequester("Question","Save the image?",#PB_MessageRequester_YesNo) If respons=#PB_MessageRequester_Yes
SaveImage(0, SaveFileRequester("","","",0),#PB_ImagePlugin_PNG,9)