Jump to content

rubic


md2

Recommended Posts

import java.awt.*;
import java.lang.Math;


public final class rubik extends java.applet.Applet
{
/**
*
*/
private static final long serialVersionUID = -202493866132165679L;
int i,j,k,n,o,p,q,lastX,lastY,dx,dy;
int rectX[],rectY[];
Color colList[],bgcolor;
final double sideVec[]={0,0,1,0,0,-1,0,-1,0,1,0,0,0,1,0,-1,0,0}; // Normal
final double corners[]={-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,1,-1,1,1,1,1,-1,1,1}; // Vertex co-ordinates
double topCorners[],botCorners[];
final int sides[]={4,5,6,7,3,2,1,0,0,1,5,4,1,2,6,5,2,3,7,6,0,4,7,3};
final int nextSide[]={2,3,4,5, 4,3,2,5, 1,3,0,5, 1,4,0,2, 1,5,0,3, 2,0,4,1};
final int mainBlocks[]={0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3};
final int twistDir[]={-1,1,-1,1, -1,1,-1,1, 1,1,1,1, 1,-1,1,-1, 1,1,1,1, -1,1,-1,1};
final int colDir[]={-1,-1,1,-1,1,-1};
final int circleOrder[]={0,1,2,5,8,7,6,3};
int topBlocks[],botBlocks[];
int sideCols[],sideW,sideH;
int dragReg,twistSide=-1;
int nearSide[],buffer[]; // Which side belongs to dragCorn
double dragCorn[],dragDir[];
double eye[]={0.3651,0.1826,-0.9129}; // Initial observer co-ordinate axes (view)
double eX[]={0.9309,-0.0716,0.3581}; // (sideways)
double eY[]; // (vertical)
double Teye[],TeX[],TeY[];
double light[],temp[]={0,0,0},temp2[]={0,0,0},newCoord[];
double sx,sy,sdxh,sdyh,sdxv,sdyv,d,t1,t2,t3,t4,t5,t6;
double phi,twistangle=0,Cphi,Sphi,currDragDir[];

boolean naturalState=true,twisting=false,OKtoDrag=false;
Math m;
Graphics offGraphics;
Image image;

public void init()
{
image=createImage(120,120); // Double buffer
offGraphics=image.getGraphics();
rectX=new int[4];
rectY=new int[4];
newCoord=new double[16]; // Projected co-ordinates (on screen)
dragDir=new double[24];
dragCorn=new double[96];
topCorners=new double[24]; // Vertex co-ordinate storage
botCorners=new double[24]; // for sub-cubes during twist
topBlocks=new int[24];
botBlocks=new int[24];
buffer=new int[12];
nearSide=new int[12];
light=new double[3];
Teye=new double[3];
TeX=new double[3];
TeY=new double[3];
currDragDir=new double[2];
eY=new double[3];
vectorProduct(eye,0,eX,0,eY,0); // Fix y axis of observer co-ordinate system
normalize(eY,0);
colList=new Color[120];
for (i=0;i<20;i++)
{
colList=new Color(255,255,255); // White
colList[i+20]=new Color(0,0,205); // Blue
colList[i+40]=new Color(255,0,255); // Red
colList[i+60]=new Color(50,255,50); // Green
colList[i+80]=new Color(255,255,0); // Yellow
colList[i+100]=new Color(255,140,0); // Orange
}
sideCols=new int[54];
for (i=0;i<54;i++)
sideCols=i/9;
bgcolor=Color.lightGray;
resize(125,125);
repaint();
}


// Various vector manipulation functions

public double scalProd(double v1[],int ix1,double v2[],int ix2)
{
return v1[ix1]*v2[ix2]+v1[ix1+1]*v2[ix2+1]+v1[ix1+2]*v2[ix2+2];
}

public double vNorm(double v[],int ix)
{
return Math.sqrt(v[ix]*v[ix]+v[ix+1]*v[ix+1]+v[ix+2]*v[ix+2]);
}

public double cosAng(double v1[],int ix1,double v2[],int ix2)
{
return scalProd(v1,ix1,v2,ix2)/(vNorm(v1,ix1)*vNorm(v2,ix2));
}

public void normalize(double v[], int ix)
{
double t=vNorm(v,ix);
v[ix]=v[ix]/t;
v[ix+1]=v[ix+1]/t;
v[ix+2]=v[ix+2]/t;
}

public void scalMult(double v[], int ix,double a)
{
v[ix]=v[ix]*a;
v[ix+1]=v[ix+1]*a;
v[ix+2]=v[ix+2]*a;
}

public void addVec(double v1[], int ix1,double v2[],int ix2)
{
v2[ix2]+=v1[ix1];
v2[ix2+1]+=v1[ix1+1];
v2[ix2+2]+=v1[ix1+2];
}

public void subVec(double v1[], int ix1,double v2[],int ix2)
{
v2[ix2]-=v1[ix1];
v2[ix2+1]-=v1[ix1+1];
v2[ix2+2]-=v1[ix1+2];
}

public void copyVec(double v1[], int ix1,double v2[],int ix2)
{
v2[ix2]=v1[ix1];
v2[ix2+1]=v1[ix1+1];
v2[ix2+2]=v1[ix1+2];
}

public void vectorProduct(double v1[],int ix1,double v2[],int ix2,
double v3[],int ix3)
{
v3[ix3]=v1[ix1+1]*v2[ix2+2]-v1[ix1+2]*v2[ix2+1];
v3[ix3+1]=v1[ix1+2]*v2[ix2]-v1[ix1]*v2[ix2+2];
v3[ix3+2]=v1[ix1]*v2[ix2+1]-v1[ix1+1]*v2[ix2];
}

public void cutUpCube()
{
boolean check;
for (i=0;i<24;i++)
{
topCorners=corners;
botCorners=corners;
}
copyVec(sideVec,3*twistSide,temp,0);
copyVec(temp,0,temp2,0);
scalMult(temp,0,1.3333);
scalMult(temp2,0,0.6667);
for (i=0;i<8;i++)
{
check=false;
for (j=0;j<4;j++)
if (i==sides[twistSide*4+j])
check=true;
if (check)
subVec(temp2,0,botCorners,i*3);
else
addVec(temp,0,topCorners,i*3);
}


for (i=0;i<24;i++)
{
topBlocks=mainBlocks;
botBlocks=mainBlocks;
}
for (i=0;i<6;i++)
{
if (i==twistSide)
{
botBlocks[i*4+1]=0;
botBlocks[i*4+3]=0;
}
else
{
k=-1;
for (j=0;j<4;j++)
if (nextSide[i*4+j]==twistSide)
k=j;
switch (k)
{
case 0:
{
topBlocks[i*4+3]=1;
botBlocks[i*4+2]=1;
break;
}
case 1:
{
topBlocks[i*4]=2;
botBlocks[i*4+1]=2;
break;
}
case 2:
{
topBlocks[i*4+2]=2;
botBlocks[i*4+3]=2;
break;
}
case 3:
{
topBlocks[i*4+1]=1;
botBlocks[i*4]=1;
break;
}
case -1:
{
topBlocks[i*4+1]=0;
topBlocks[i*4+3]=0;
break;
}
}
}
}
}



public boolean mouseDrag(java.awt.Event evt, int x, int y)
{
boolean check;
double x1,x2,y1,y2,alpha,beta;

if ((!twisting)&&(OKtoDrag))
{
OKtoDrag=false;
check=false;
for (i=0;i<dragReg;i++)
{
x1=dragCorn[i*8+1]-dragCorn[i*8];
x2=dragCorn[i*8+5]-dragCorn[i*8+4];
y1=dragCorn[i*8+3]-dragCorn[i*8];
y2=dragCorn[i*8+7]-dragCorn[i*8+4];
alpha=(y2*(lastX-dragCorn[i*8])-y1*(lastY-dragCorn[i*8+4]))/
(x1*y2-y1*x2);
beta=(-x2*(lastX-dragCorn[i*8])+x1*(lastY-dragCorn[i*8+4]))/
(x1*y2-y1*x2);
if ((alpha>0)&&(alpha<1)&&(beta>0)&&(beta<1))
{
currDragDir[0]=dragDir[i*2];
currDragDir[1]=dragDir[i*2+1];
d=currDragDir[0]*(x-lastX)+currDragDir[1]*(y-lastY);
d=d*d/((currDragDir[0]*currDragDir[0]+currDragDir[1]*currDragDir[1])*
((x-lastX)*(x-lastX)+(y-lastY)*(y-lastY)));
if (d>0.6)
{
check=true;
twistSide=nearSide;
i=100;
}
}
}
if (check)
{
if (naturalState)
{
cutUpCube();
naturalState=false;
}
twisting=true;
phi=0.02*(currDragDir[0]*(x-lastX)+currDragDir[1]*(y-lastY))/
Math.sqrt(currDragDir[0]*currDragDir[0]+currDragDir[1]*currDragDir[1]);
repaint();
return false;
}
}

OKtoDrag=false;
if (!twisting)
{
dx=lastX-x;
copyVec(eX,0,temp,0);
scalMult(temp,0,((double)dx)*0.016);
addVec(temp,0,eye,0);
vectorProduct(eY,0,eye,0,eX,0);
normalize(eX,0);
normalize(eye,0);
dy=y-lastY;
copyVec(eY,0,temp,0);
scalMult(temp,0,((double)dy)*0.016);
addVec(temp,0,eye,0);
vectorProduct(eye,0,eX,0,eY,0);
normalize(eY,0);
normalize(eye,0);
lastX=x;
lastY=y;
repaint();
}
else
{
phi=0.02*(currDragDir[0]*(x-lastX)+currDragDir[1]*(y-lastY))/
Math.sqrt(currDragDir[0]*currDragDir[0]+currDragDir[1]*currDragDir[1]);
repaint();
}
return false;
}

public boolean mouseDown(java.awt.Event evt, int x, int y)
{
lastX=x;
lastY=y;
OKtoDrag=true;
return false;
}

public boolean mouseUp(java.awt.Event evt, int x, int y)
{
int quads;
double qu;
if (twisting)
{
twisting=false;
twistangle+=phi;
phi=0;
qu=twistangle;
while (qu<0)
qu+=125.662;
quads=((int)(qu*3.183));
if (((quads % 5)==0)||((quads % 5)==4))
{
quads=((quads+1)/5) % 4;
if (colDir[twistSide]<0)
quads=(4-quads) % 4;
twistangle=0;
naturalState=true;
colorTwist(twistSide,quads);
}
repaint();
}
return false;
}

public void colorTwist(int sideNum, int quads)
{
int i,j,k,l=0;
k=quads*2;
for (i=0;i<8;i++)
{
buffer[k]=sideCols[sideNum*9+circleOrder];
k=(k+1) % 8;
}
for (i=0;i<8;i++)
sideCols[sideNum*9+circleOrder]=buffer;
k=quads*3;
for (i=0;i<4;i++)
{
for (j=0;j<4;j++)
if (nextSide[nextSide[sideNum*4+i]*4+j]==sideNum)
l=j;
for (j=0;j<3;j++)
{
switch(l)
{
case 0:
buffer[k]=sideCols[nextSide[sideNum*4+i]*9+j];
break;
case 1:
buffer[k]=sideCols[nextSide[sideNum*4+i]*9+2+3*j];
break;
case 2:
buffer[k]=sideCols[nextSide[sideNum*4+i]*9+8-j];
break;
case 3:
buffer[k]=sideCols[nextSide[sideNum*4+i]*9+6-3*j];
break;
default:
break;
}
k=(k+1) % 12;
}
}
k=0;
for (i=0;i<4;i++)
{
for (j=0;j<4;j++)
if (nextSide[nextSide[sideNum*4+i]*4+j]==sideNum)
l=j;
for (j=0;j<3;j++)
{
switch(l)
{
case 0:
sideCols[nextSide[sideNum*4+i]*9+j]=buffer[k];
break;
case 1:
sideCols[nextSide[sideNum*4+i]*9+2+3*j]=buffer[k];
break;
case 2:
sideCols[nextSide[sideNum*4+i]*9+8-j]=buffer[k];
break;
case 3:
sideCols[nextSide[sideNum*4+i]*9+6-3*j]=buffer[k];
break;
default:
break;
}
k++;
}
}
}

public void paint(Graphics g)
{
dragReg=0;
offGraphics.setColor(bgcolor);
offGraphics.fillRect(0,0,120,120);
if (naturalState)
fixBlock(eye,eX,eY,corners,mainBlocks,0);
else
{
Cphi=Math.cos(phi+twistangle);
Sphi=-Math.sin(phi+twistangle);
copyVec(eye,0,Teye,0);
copyVec(eX,0,TeX,0);

switch(twistSide)
{
case 0: // z
Teye[0]=Cphi*eye[0]+Sphi*eye[1];
TeX[0]=Cphi*eX[0]+Sphi*eX[1];
Teye[1]=-Sphi*eye[0]+Cphi*eye[1];
TeX[1]=-Sphi*eX[0]+Cphi*eX[1];
break;
case 1: // -z
Teye[0]=Cphi*eye[0]-Sphi*eye[1];
TeX[0]=Cphi*eX[0]-Sphi*eX[1];
Teye[1]=Sphi*eye[0]+Cphi*eye[1];
TeX[1]=Sphi*eX[0]+Cphi*eX[1];
break;
case 2: // -y
Teye[0]=Cphi*eye[0]-Sphi*eye[2];
TeX[0]=Cphi*eX[0]-Sphi*eX[2];
Teye[2]=Sphi*eye[0]+Cphi*eye[2];
TeX[2]=Sphi*eX[0]+Cphi*eX[2];
break;
case 3: // x
Teye[1]=Cphi*eye[1]+Sphi*eye[2];
TeX[1]=Cphi*eX[1]+Sphi*eX[2];
Teye[2]=-Sphi*eye[1]+Cphi*eye[2];
TeX[2]=-Sphi*eX[1]+Cphi*eX[2];
break;
case 4: // y
Teye[0]=Cphi*eye[0]+Sphi*eye[2];
TeX[0]=Cphi*eX[0]+Sphi*eX[2];
Teye[2]=-Sphi*eye[0]+Cphi*eye[2];
TeX[2]=-Sphi*eX[0]+Cphi*eX[2];
break;
case 5: // -x
Teye[1]=Cphi*eye[1]-Sphi*eye[2];
TeX[1]=Cphi*eX[1]-Sphi*eX[2];
Teye[2]=Sphi*eye[1]+Cphi*eye[2];
TeX[2]=Sphi*eX[1]+Cphi*eX[2];
break;
default:
break;
}
vectorProduct(Teye,0,TeX,0,TeY,0);
if (scalProd(eye,0,sideVec,twistSide*3)<0) // Top facing away? Draw it first
{
fixBlock(Teye,TeX,TeY,topCorners,topBlocks,2);
fixBlock(eye,eX,eY,botCorners,botBlocks,1);
}
else
{
fixBlock(eye,eX,eY,botCorners,botBlocks,1);
fixBlock(Teye,TeX,TeY,topCorners,topBlocks,2);
}
}
g.drawImage(image,0,0,this);
}

public void update(Graphics g)
{
paint(g);
}

// Draw cube or sub-cube
public void fixBlock(double beye[],double beX[],double beY[],
double bcorners[],int bblocks[],int mode)
{
copyVec(beye,0,light,0);
scalMult(light,0,-3);
addVec(beX,0,light,0);
subVec(beY,0,light,0);

for (i=0;i<8;i++) // Project 3D co-ordinates into 2D screen ones
{
newCoord[i*2]=(60+35.1*scalProd(bcorners,i*3,beX,0));
newCoord[i*2+1]=(60-35.1*scalProd(bcorners,i*3,beY,0));
}

for (i=0;i<6;i++)
{
if (scalProd(beye,0,sideVec,3*i)>0.001) // Face towards us? Draw it.
{
k=(int)(9.6*(1-cosAng(light,0,sideVec,3*i)));
offGraphics.setColor(Color.black);
for (j=0;j<4;j++) // Find corner co-ordinates
{
rectX[j]=(int)newCoord[2*sides[i*4+j]];
rectY[j]=(int)newCoord[2*sides[i*4+j]+1];
}
offGraphics.fillPolygon(rectX,rectY,4); // First draw black
sideW=bblocks[i*4+1]-bblocks[i*4];
sideH=bblocks[i*4+3]-bblocks[i*4+2];
if (sideW>0)
{
sx=newCoord[2*sides[i*4]];
sy=newCoord[2*sides[i*4]+1];
sdxh=(newCoord[2*sides[i*4+1]]-sx)/sideW;
sdxv=(newCoord[2*sides[i*4+3]]-sx)/sideH;
sdyh=(newCoord[2*sides[i*4+1]+1]-sy)/sideW;
sdyv=(newCoord[2*sides[i*4+3]+1]-sy)/sideH;
p=bblocks[i*4+2];
for (n=0;n<sideH;n++) // Then draw colored fields
{
q=bblocks[i*4];
for (o=0;o<sideW;o++)
{
rectX[0]=(int)(sx+(o+0.1)*sdxh+(n+0.1)*sdxv);
rectX[1]=(int)(sx+(o+0.9)*sdxh+(n+0.1)*sdxv);
rectX[2]=(int)(sx+(o+0.9)*sdxh+(n+0.9)*sdxv);
rectX[3]=(int)(sx+(o+0.1)*sdxh+(n+0.9)*sdxv);
rectY[0]=(int)(sy+(o+0.1)*sdyh+(n+0.1)*sdyv);
rectY[1]=(int)(sy+(o+0.9)*sdyh+(n+0.1)*sdyv);
rectY[2]=(int)(sy+(o+0.9)*sdyh+(n+0.9)*sdyv);
rectY[3]=(int)(sy+(o+0.1)*sdyh+(n+0.9)*sdyv);
offGraphics.setColor(colList[20*sideCols[i*9+p*3+q]+k]);
offGraphics.fillPolygon(rectX,rectY,4);
q++;
}
p++;
}
}
switch (mode) // Determine allowed drag regions and directions
{
case 0: // Just the normal cube
t1=sx;
t2=sy;
t3=sdxh;
t4=sdyh;
t5=sdxv;
t6=sdyv;
for (j=0;j<4;j++)
{
dragCorn[8*dragReg]=t1;
dragCorn[8*dragReg+4]=t2;
dragCorn[8*dragReg+3]=t1+t5;
dragCorn[8*dragReg+7]=t2+t6;
t1=t1+t3*3;
t2=t2+t4*3;
dragCorn[8*dragReg+1]=t1;
dragCorn[8*dragReg+5]=t2;
dragCorn[8*dragReg+2]=t1+t5;
dragCorn[8*dragReg+6]=t2+t6;
dragDir[dragReg*2]=t3*twistDir[i*4+j];
dragDir[dragReg*2+1]=t4*twistDir[i*4+j];
d=t3;
t3=t5;
t5=-d;
d=t4;
t4=t6;
t6=-d;
nearSide[dragReg]=nextSide[i*4+j];
dragReg++;
}
break;
case 1: // The large sub-cube
break;
case 2: // The small sub-cube (twistable part)
if ((i!=twistSide)&&(sideW>0))
{
if (sideW==3) // Determine positive drag direction
if (bblocks[i*4+2]==0)
{
dragDir[dragReg*2]=sdxh*twistDir[i*4];
dragDir[dragReg*2+1]=sdyh*twistDir[i*4];
}
else
{
dragDir[dragReg*2]=-sdxh*twistDir[i*4+2];
dragDir[dragReg*2+1]=-sdyh*twistDir[i*4+2];
}
else
if (bblocks[i*4]==0)
{
dragDir[dragReg*2]=-sdxv*twistDir[i*4+3];
dragDir[dragReg*2+1]=-sdyv*twistDir[i*4+3];
}
else
{
dragDir[dragReg*2]=sdxv*twistDir[i*4+1];
dragDir[dragReg*2+1]=sdyv*twistDir[i*4+1];
}
for (j=0;j<4;j++)
{
dragCorn[dragReg*8+j]=newCoord[2*sides[i*4+j]];
dragCorn[dragReg*8+4+j]=newCoord[2*sides[i*4+j]+1];
}
nearSide[dragReg]=twistSide;
dragReg++;
}
break;
default:
break;
}
}
}
}
}

Link to comment
Share on other sites

there is no question as far as I can understand; thread locked.

 

!

Moderator Note

 

md2

 

If we cannot understand your next post then your rights to post may be rescinded. You have been warned.

 

 

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.