The magazine of the Melbourne PC User Group

The hypercube: Exploring the
fourth dimension, and further

Ken Holmes
kholmes@melbpc.org.au

With apologies to those who know all about the hypercube, this is written for those who don't, to indicate the interesting shapes you can get in 3D by extending 3D mathematics into an imaginary fourth dimension. I first learnt of this from Prof. A K Dewdney's "Computer Recreations" column in the April 1986 issue of Scientific American.

Let us imagine that another Big Bang created a 2D universe and we are 2D critters living in a plane world. We come to appreciate our position in relation to x and y axes at right angles, can perceive points, lines, squares and circles and can do Pythagoras. Our 2D mathematicians (2DMs) can rotate a point about the origin with two equations looking like "SUB rot" in the QBasic code in Listing 1. As it rotates, the new x and y co-ordinates each depend on the old x and y, and the angle of rotation. We might consider that the simplest square has its corners at the four points (x,y) = (ñ1, ñ1)


Figure 1  Hypercube with one cube smaller (Hypertrapezoid?)


Figure 2 Hypertrapezoid after several real and unreal rotations

Then these pesky 2DMs tell us there is a third imaginary axis, z, which is at right angles to each axis, x and y. Unbelievable! Moreover, they have the hide to suggest they can put similar squares at z = -1 and +1, which will define a "cube" with eight corners at (x, y, z) = (ñ1, ñ1, ñ1). What's more, they say, they will apply their rotation equations to the x and z or to the y and z pairs or, the devils, to both pairs. When they plot the eight points with the new x and y co-ordinates and join them up we see a surprising figure. There is no indication of z co-ordinates and, even if there were, we are quite incapable of visualising the 3D cube. Of course, we know there isn't really a z axis, but we've surely seen some interesting shapes in our 2D world. Let's face it, life is pretty dreary here in 2D and we welcome anything new.

Happily, we do live in 3D, or at least we think we do, and know that the "surprising figure" seen by our 2D friends was an orthogonal projection of the cube onto their plane. We rotate things with gay abandon about any axis; when we keep x constant and relate y and z by the equations, we call it "rotation about the x axis", but, for our present purposes we are going to call this "rotation of the y and z axes", which is how the point sees it. Of course, we observers are sort of attached to the axes and see it as a rotation of the point. Now, we have our own set of pesky 3DMs who tell us there is a fourth "unreal" axis, which we'll call u, and, get this, they insist that it is at right angles to each of x, y and z. You don't get it, do you? And neither do I, because we just can't visualise 4D, but let's go along with it. Moreover they have the hide to suggest putting cubes at u = -1 and +1, which will define a "hypercube" with eight corners at (u, x, y, z) = (ñ1, ñ1, ñ1, ñ1).

What's more, they are prepared to rotate any of the six possible pairs of the four axes. Again, we can only plot something using the real co-ordinates and, working on 2D paper or screens, we can only present 2D information. We are used to depicting 3D on a flat surface and are able to recognise familiar 3D objects, but if we really want to see 3D, particularly with unfamiliar objects, we need some stereo device giving each eye a different view. The most readily available and cheapest is the mirror. Listing 1 will give you a stereo view of the hypercube where you can at least see its orthogonal projection onto 3D space, rotating in any of the six modes.

At the start, we will see a single cube since both cubes have the same x/y/z and the difference in u is not visible to us. If we rotate any pair of real axes, we will see a rotating cube with, say, x and y swapping information so that each co-ordinate varies sinusoidally. They are 90 degrees out of phase and we might say that the second one is varying osinusoidally. We can see both cubes if we change the size of one and pressing "r" four or five times in our program will halve the size of the cube at u = -1. This should probably be called a "hypertrapezoid", as illustrated by Figure 1. Things get really (or unreally?) interesting when we rotate u with one of x/y/z; if, say, x is swapping information with u, we will see the effect on x but not on the invisible u. The two cubes have different u values, so the variation of their x values will be quite different; they will move relative to each other and change shape in weird ways. At first sight, you may get the impression it is rotating about the y axis because of the sinusoidal motion along the x axis but, if you look carefully, their is no motion along the z axis. You would not be able to assess this in 2D, non-stereo. This program rotates the axes continuously and, if you return to a rotation of real axes the figure will rotate without changing shape--until you select an unreal rotation again. Figure 2 is the sort of configuration after several real and unreal rotations.

Note: Prof Dewdney's article sticks with the hypercube but does a perspective projection from the point (3, 0, 0, 0), in the fourth dimension, onto the 3D hypersurface at u = 1. Since the cube at u = -1 is twice as far away as the one at u = 1, it appears half sized and his starting figure is identical to Figure 1, but unreal rotations produce much greater, and more interesting, distortions due to the perspective from close up in the fourth dimension. Alternative code in "SUB plot" allows you to see this.

The program

The EGA screen mode has two "pages" which can be "visual" (on screen) and/or "active" (any code will write to it). Normally, page 0 is both, and page 1 is unused, but if we make page 1 active we can draw on it off screen, in memory. If we then swap pages we can see page 1 while drawing the next picture off screen on page 0. Thus we easily achieve animation. The WINDOW is sized so that the ñ1 sized figure has room to rotate on the right half of the screen and the left half can accept the flipped left eye view. The corners 0 to 15 have their u/x/y/z (or 0/1/2/3) co-ordinates stored in the two dimensional array corn(15,3), and trail(32) is a sequence, supplied in Scientific American, for drawing the 32 lines in a string passing through each of the 16 points twice. I have contrived a colour sequence in col(32) so that, for example, all lines originally parallel to the x axis are green. These arrays are filled by reading the DATA at the end of the code.

For convenience, we use the ASCII value for the keys x/y/z/1/2/3 in the variable "rotate" to choose which mode of rotation occurs. Whilst x gives rotation about the x axis, 1 gives an oscillation along it. Keys r and e cause a reduction or an expansion of the cube at u = -1 and keys f and s will make the rotation faster or slower by changing the angle change between plots. For a bit of fun, c will toggle screen clearance off/on to give nice changing patterns of colour on the screen. The display is simply wireline and the fixed trail of line drawing means that, half the time, a more distant line is drawn over a closer one so that the figure is ambiguous, particularly with different colours. Rectifying this needs some tedious code to draw furthest lines first. For this article, the program was extended to write a file for the POVRay ray tracing program with rods replacing each line. This produced the figures with no mistakes since each ray from eye to screen only records the first object and ignores any beyond it. Also we could have a more substantial object. Figures 1 and 2 are not stereo, to save magazine space as we have something better to come.

How about 5D, and more?

There is no reason why we shouldn't go on to the fifth dimension, which we'll call v (very unreal), simply because it is not there, just like Neverest. We can put hypercubes at v = -1 and +1 and join them up, giving 32 points, at (u, v, x, y, z) = (ñ1, ñ1, ñ1, ñ1, ñ1), needing 80 connecting lines; Let's call it the Ultracube. We'll use keys 4/5/6 for rotations of the v axis with one of x/y/ z. The screen is a bit crowded but it works and, with screenclear off, the colour patterns are even more intricate. The ray tracer was used to produce views for each eye, which were spliced to give the Figure 3 stereo. Whilst you wouldn't wish to build this structure, except for a bet, there is a pleasing logicality about it, with all rods of the same colour remaining parallel and of equal length. Converting it to an ultra-trapezoid would soon change that! Perhaps it would make a sculpture, or a climbing frame for a playground, provided an unreal rotation were not performed with a child aboard.


Figure 3 The 5D Ultracube. 

Place mirror edge up centreline, mirror facing left. Right eye looks at right screen, left eeye at reflection in mirror.

We could continue to 6D adding axis w (double unreal) by putting an ultracube at w = -1 and +1, needing 64 points, at (u, v, w, x, y, z) = (ñ1, ñ1, ñ1, ñ1, ñ1, ñ1) and 192 lines, but I'll spare you that and refrain from giving it a name. The separation of figures with the first rotation involving each unreal axis is reminiscent of the mitosis (dividing) of living cells (if we didn't draw the lines connecting corresponding points on each cube).

HYPRCUBE.LZH will be on our BBS, containing the .BAS and .EXE files for both the 4D and the 5D programs. Unless we get too many complaints about the suitability of this sort of thing for a family magazine, or we lose too many members into hyperspace, I may submit a further (shorter) article on the Hypersphere which produces quite different projections onto 3D space.

 

Program listing of HYPRCUBE.BAS
Download source listing

'HYPRCUBE.BAS
  'Rotates hypercube about real and imaginary axes>
DECLARE SUB rot (a, b) 'serves 6 possible pairs of axes
DECLARE SUB plot ()    'plots on active screen (in memory)
DIM SHARED corn(15, 3)            '16 hypercube vertices
DIM SHARED trail(32) AS INTEGER   'line drawing sequence
DIM SHARED col(32) AS INTEGER     'line colours sequence
DIM rotate AS INTEGER    'rotation mode(uses ASCII value)
DIM SHARED sn, cs AS SINGLE    'sin & cos(rotation angle)
FOR n = 0 TO 15: FOR m = 0 TO 3   'read Hypercube...
  READ corn(n, m): NEXT: NEXT     '...coords, (u,x,y,z)
FOR n = 0 TO 32: READ trail(n): NEXT    'line sequence
FOR n = 0 TO 32: READ col(n): NEXT <    'colour sequence
start:     'rotation on x(ASCII=120) axis, 0.01 radians
ky = 120: ang = .01: sn = SIN(ang): cs = COS(ang)
SCREEN 9: WINDOW (-4.8, -2.4)-(1.6, 2.4)    'EGA screen...
DO <@146>looping         '...which has two pages for animation
key$ = INKEY$            'check for key press
IF key$ <> "" THEN ky = ASC(key$)     'read key ASCII value
SELECT CASE ky          'action is based on key ASCII value
 CASE 120 TO 122: rotate = ky    'rot. about x,y or z axis
 CASE 49 TO 51: rotate = ky   '1,2 or 3 - rot x/y/z with u
 CASE 102: ang = ang + .002          '"f" makes faster
  sn = SIN(ang): cs = COS(ang): ky = 0
 CASE 115: ang = ang - .002          '"s" makes slower
  sn = SIN(ang): cs = COS(ang): ky = 0     'nullify ky
 CASE 32: rotate = 0          'spacebar stops rotation
 CASE 101: FOR n = 0 TO 7: FOR m = 1 TO 3 
  corn(n, m) = corn(n, m) * 1.1: NEXT: NEXT 'e expands.. 
  ky = 0   '...cube at u = -1 (once, then ky nullified)
 CASE 114: FOR n = 0 TO 7: FOR v = 1 TO 3 
  corn(n, m) = corn(n, m) * .9: NEXT: NEXT   'r reduces..
  ky = 0      '...cube at u = -1 (once, then ky nullified)
 CASE 99: c = 1 - c: ky = 0 <   'c toggles 0/1 (CLS on/off)
END SELECT
SELECT CASE rotate       'current rotation mode
 CASE 120: CALL rot(2, 3)        'y and z axes
 CASE 121: CALL rot(3, 1)        'z and x axes
 CASE 122: CALL rot(1, 2)        'x and y axes
 CASE 49: CALL rot(1, 0)         'x and u axes
 CASE 50: CALL rot(2, 0)         'y and u axes
 CASE 51: CALL rot(3, 0)         'z and u axes
END SELECT
IF c = 0 THEN CLS       'if c = 1, screen not cleared
plot <@146>plots on active page in memory to be swapped...
p = 1 - p: SCREEN , , p, 1 - p     '...with visual page
FOR n = 1 TO 500: NEXT     'counted delay for viewing time
LOOP UNTIL ky = 27         'until Escape key hit
END <      'Now for coordinates (u, x, y, z) of ...
'points 0-15. Points 0-7 are at u=-1 & 8-15 are at u=+1
DATA -1,-1,-1,-1, -1,-1,-1, 1, -1,-1, 1,-1, -1,-1, 1, 1
DATA -1, 1,-1,-1, -1, 1,-1, 1, -1, 1, 1,-1, -1, 1, 1, 1
DATA  1,-1,-1,-1,  1,-1,-1, 1,  1,-1, 1,-1,  1,-1, 1, 1
DATA  1, 1,-1,-1,  1, 1,-1, 1,   1, 1, 1,-1, 1, 1, 1, 1
   'Drawing trail goes through points twice, in order -
DATA 0,1,3,2,6,14,10,8,9,11,3,7,15,14,12,13,9
DATA 1,5,7,6,4,12,8,0,4,5,13,15,11,10,2,0
   'lines are coloured in following order 
DATA 0,4,3,4,2,1,2,3,4,3,1,2,1,4,3,4,2
DATA 1,2,3,4,3,1,2,1,2,4,1,3,2,4,1,3

SUB plot   'rt & lft eye plots on active page in memory
FOR n = 0 TO 32: s = trail(n)     'use 'trail' sequence
    'for orthogonal projection, use next line OR ....
  x = corn(s, 1): y = corn(s, 2): z = corn(s, 3)
    '....for perspective projection, use next two lines
  'f = 2 / (3 - corn(s, 0))
  'x = f* corn(s,1): y = f* corn(s,2): z = f* corn(s,3) 
  fz = z / (z + 10): xr = x - (x + .8) * fz 
  xl = -3.2 - x - (x + 2.4) * fz: yb = y - y * fz
  IF n >> 0 THEN      'can't draw line with only point 0
   LINE (xs, yc)-(xr, yb), col(n)    'right eye
   LINE (xm, yc)-(xl, yb), col(n)    'left eye
  END IF 
  xs = xr: xm = xl: yc = yb   'start points for next line
NEXT<R>
END SUB

SUB rot (a, b)    'affects coords a/b(any pair of u,x,y,z)
FOR m = 0 TO 15       'rotate 16 vertices
  temp = corn(m, a) * cs + corn(m, b) * sn   '=new (m,a)
  corn(m, b) = corn(m, b) * cs - corn(m, a) * sn
  corn(m, a) = temp: NEXT   'need original (m,a) in eqn.2
END SUB

Reprinted from the July 1999 issue of PC Update, the magazine of Melbourne PC User Group, Australia

 

[About Melbourne PC User Group]