Author Topic: Generating a cube  (Read 2877 times)

0 Members and 1 Guest are viewing this topic.

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Generating a cube
« on: May 05, 2008 »
Okay, it sounds *really* obvious, but I'm looking for a clever way to make it small.

Nothing special on the cube - 8 vertices, 6 sides, 12 edges:


Generating the vertices is trivial.
Looping through all vertex-indices i [0..7], we get the x,y,z-coordinates in [0..1] with:
Code: [Select]
x= (i+1)>>1&1;
y= i >> 1 & 1;
z= i >> 2 & 1;
(Swapping 2/3 and 6/7 simplifies x to "i & 1", but keeping them clockwise gives ready-to-use quad-order).

Now to the interessting part - extracting the 12 edges.
Each edge is defined by two vertex-indices:
0-1, 1-2, 2-3, 3-0, 4-5, 5-6, 6-7, 7-4, 0-4, 1-5, 2-6, 3-7
Since each index [0..7] requires only 3 bits, we could simply store these, eg each pair in 1 byte (using 4bits each for readability) - resulting in 12 bytes of storage.

Looping through all edges e we can look up the edge-indices from the table:
Code: [Select]
char edges[12]= {0x01,0x12,0x23,0x30,0x45,0x56,0x67,0x74, 0x04,0x15,0x26,0x37};

v1= edges[e] >> 4 & 0xf;
v2= edges[e] & 0xf;

But looking at the upper nibble of each byte (012345670123) we certainly won't store that, but get v1 from e:
Code: [Select]
v1= e & 7;
All that's left are 12 3bit values (=36bit; how unhandy).
So all we need is a function to get v2 from e:
Code: [Select]
input:  0123 4567 89AB
output: 1230 5674 4567

Obviously the function should be smaller than space (+extraction) needed to store the table...
Ideas anyone? :)

Challenge Trophies Won:

Offline rain_storm

  • Here comes the Rain
  • DBF Aficionado
  • ******
  • Posts: 3088
  • Karma: 182
  • Rain never hurt nobody
    • View Profile
    • org_100h
Re: Generating a cube
« Reply #1 on: May 05, 2008 »
Shouldnt be too dificult to generate the edges altogether

edges on front face -
 0x01 0x12 0x23 0x30 ; high nibble is always low_nibble -1 << 4

edges on back face -
 0x45 0x56 0x67 0x74 ; front face + 0x44

edges on side faces -
 0x04 0x15 0x26 0x37 ; front face + 0x01
 0x04 0x15 0x26 0x37 ; front face and 0xf0, back face >> 4
 

edit:
 My bad edges on the side are wrong there should be using back face high nibble instead
« Last Edit: May 05, 2008 by rain_storm »

Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Re: Generating a cube
« Reply #2 on: May 05, 2008 »
Thanks, that looks pretty compact and was probably just too obvious to see :)
Code: [Select]
void createCubeEdges(int *dst)
{
for (int v1=0;v1<4;v1++)
{
int v2= (v1+1) & 3;
dst[0]= v1;
dst[1]= v2;
dst[8]= v1+4;
dst[9]= v2+4;
dst[16]= v1;
dst[17]= v1+4;
dst+=2;
}
}

My existing approach was rather confused:
Code: [Select]
for (int i=0;i<12;i++)
{
int v1= (i & 3);
int v2= (v1 + ((i>>3)^1)) & 3;
*dst++= v1 + (i&4);
*dst++= v2 + ((i>=4)<<2);
}
Challenge Trophies Won: