我写这篇文章完全出于兴趣,不过也许有用也说不定。
额编辑还不熟练,第二次发表文章,写个hello world。嘿嘿。代码运行起来没问题,操作是键盘的上下左右和WASD分别是绕X,Y轴旋转和绕X,Y旋转。没错,上下左右隐藏了W轴,(第四轴我暂且叫他W轴)而WASD隐藏了Z轴
上面有个绕W轴旋转的方法,其实根据
while(true){
ck[i]=Math.pow(t[i]-c[i],2);
if(i==3){
e=Math.pow(ck[0]+ck[1]+ck[2]+ck[3], 0.5);
break;
}
i++;
}
i=0;
if(e-200>2||e-200<-2)System.out.println(e);
这个计算,往往表示出错。就是e(四维棱长变了)。由于是小白变量名都很奇怪,所以原谅我。也许看着看着就懂了。
然后上代码
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyVetoException;import javax.swing.JFrame;
class line extends JFrame{
double wvec= Math.cos(Math.toRadians(30));
double wves= Math.sin(Math.toRadians(30));
boolean bo=true;
int cx=500,cy=500;
public void rect(Graphics scr,double[][] a){//3:x 2:y 1:z 0:a
int i=0;double e;
double[] ck=new double[4]; for(double[] t:a){for(double[] c:a){
//scr.drawLine((int)(t[3]+cx+t[0]*wvec), (int)(t[2]+cy+t[0]*wves), (int)(c[3]+cx+t[0]*wvec), (int)(c[2]+cy+t[0]*wves));
while(true){
ck[i]=Math.pow(t[i]-c[i],2);
if(i==3){
e=Math.pow(ck[0]+ck[1]+ck[2]+ck[3], 0.5);
break;
}
i++;
}
i=0;
if(e-200<10&&e-200>-10){scr.drawLine((int)t[3]+cx, (int)t[2]+cy, (int)c[3]+cx, (int)c[2]+cy);}
}}
i=0;
//用于证实四维方块边大小没变
/*while(true){
ck[i]=Math.pow(a[0][i]-a[1][i],2);
if(i==3){
e=Math.pow(ck[0]+ck[1]+ck[2]+ck[3], 0.5);
break;
}
i++;
}
if(e-200>2||e-200<-2)System.out.println(e);*/
}
public double[][] erjinzhi(){
double[][] dot=new double[16][4];
int i=3;
int a=0;
double[] be={100,100,100,100};
while(true){
if(i==3){dot[a]=be.clone();a++;}
if(be[i]>0){be[i]*=-1;
if(be[0]==be[1]&&be[2]==be[3]&&be[0]==-100&&be[1]==be[2]){dot[a]=be.clone();break;}
i=3;continue;}
if(be[i]<0){be[i]*=-1;}
if(i==0){i=3;}
i--;}
return (double[][])dot;
}
double abr,R,R2;
//隐藏0 W轴的xyz旋转
public void turnY(double v,double[][] pos){
int i=0;
double wv= Math.toRadians(v);
double rep= Math.toRadians(45);
for(double[] c:pos)
{
if(pos[i][1]<3&&pos[i][1]>-3)pos[i][1]=-(pos[i][1]/Math.abs(pos[i][1]))*3;
R=Math.pow(pos[i][1]*pos[i][1]+pos[i][3]*pos[i][3],0.5);
abr=Math.atan(pos[i][1]/pos[i][3])-wv;
pos[i][1]=pos[i][1]/Math.abs(pos[i][1])*R*Math.abs(Math.sin(abr));
pos[i][3]=pos[i][3]/Math.abs(pos[i][3])*R*Math.cos(abr);
i++;
}
}
public void turnX(double v,double[][] pos){
int i=0;
double wv= Math.toRadians(v);
for(double[] c:pos)
{ if(pos[i][1]<3&&pos[i][1]>-3)pos[i][1]=-(pos[i][1]/Math.abs(pos[i][1]))*3;
R=Math.pow(pos[i][1]*pos[i][1]+pos[i][2]*pos[i][2],0.5);
abr=Math.atan(pos[i][1]/pos[i][2])-wv;
pos[i][1]= (pos[i][1]/Math.abs(pos[i][1])*R*Math.abs(Math.sin(abr)));
pos[i][2]= (pos[i][2]/Math.abs(pos[i][2])*R*Math.cos(abr));
i++;
}
}
public void turnZ(double v,double[][] pos){
int i=0;
double wv= Math.toRadians(v);
for(double[] c:pos)
{ if(pos[i][3]<3&&pos[i][3]>-3)pos[i][3]=-(pos[i][3]/Math.abs(pos[i][3]))*3;
R=Math.pow(pos[i][3]*pos[i][3]+pos[i][2]*pos[i][2],0.5);
abr=Math.atan(pos[i][3]/pos[i][2])-wv;
pos[i][3]= pos[i][3]/Math.abs(pos[i][3])*R*Math.abs(Math.sin(abr));
pos[i][2]= pos[i][2]/Math.abs(pos[i][2])*R*Math.cos(abr);
i++;
}
}
boolean[] f=new boolean[16];
int k=0;
//四维长方体
public void turnW(double v,double[][] pos){
int i=0;
double a,b;
double wv= Math.toRadians(v);
for(double[] c:pos)
{
if(pos[i][0]<3&&pos[i][0]>-3)pos[i][0]=-(pos[i][0]/Math.abs(pos[i][0]))*3;
a=pos[i][3]*pos[i][3]+pos[i][2]*pos[i][2]+pos[i][1]*pos[i][1];
b=pos[i][0]*pos[i][0];
R=Math.pow(a, 0.5);
if(f[i])R=-R;
R2=Math.pow(a+b,0.5);
abr=Math.atan(pos[i][0]/R)-wv;
pos[i][0]= pos[i][0]/Math.abs(pos[i][0])*R2*Math.abs(Math.sin(abr));
a=R2*Math.cos(abr);
if(a<0&&k<8){f[i]=!f[i];k++;}
pos[i][1]=a/R*pos[i][1];
pos[i][2]=a/R*pos[i][2];
pos[i][3]=a/R*pos[i][3];
i++;
}
if(k>7)k++;
if(k==30)k=0;
}
//隐藏z轴的四维旋转public void zturnY(double v,double[][] pos){
int i=0;
double wv= Math.toRadians(v);
double rep= Math.toRadians(45);
for(double[] c:pos)
{
if(pos[i][0]<3&&pos[i][0]>-3)pos[i][0]=-(pos[i][0]/Math.abs(pos[i][0]))*3;
R=Math.pow(pos[i][0]*pos[i][0]+pos[i][3]*pos[i][3],0.5);
abr=Math.atan(pos[i][0]/pos[i][3])-wv;
pos[i][0]=pos[i][0]/Math.abs(pos[i][0])*R*Math.abs(Math.sin(abr));
pos[i][3]=pos[i][3]/Math.abs(pos[i][3])*R*Math.cos(abr);
i++;
}
}public void zturnX(double v,double[][] pos){
int i=0;
double wv= Math.toRadians(v);
for(double[] c:pos)
{ if(pos[i][0]<3&&pos[i][0]>-3)pos[i][0]=-(pos[i][0]/Math.abs(pos[i][0]))*3;
R=Math.pow(pos[i][0]*pos[i][0]+pos[i][2]*pos[i][2],0.5);
abr=Math.atan(pos[i][0]/pos[i][2])-wv;
pos[i][0]= (pos[i][0]/Math.abs(pos[i][0])*R*Math.abs(Math.sin(abr)));
pos[i][2]= (pos[i][2]/Math.abs(pos[i][2])*R*Math.cos(abr));
i++;
}
}public void zturnW(double v,double[][] pos){
int i=0;
double wv= Math.toRadians(v);
for(double[] c:pos)
{ if(pos[i][3]<3&&pos[i][3]>-3)pos[i][3]=-(pos[i][3]/Math.abs(pos[i][3]))*3;
R=Math.pow(pos[i][3]*pos[i][3]+pos[i][2]*pos[i][2],0.5);
abr=Math.atan(pos[i][3]/pos[i][2])-wv;
pos[i][3]= pos[i][3]/Math.abs(pos[i][3])*R*Math.abs(Math.sin(abr));
pos[i][2]= pos[i][2]/Math.abs(pos[i][2])*R*Math.cos(abr);
i++;
}
}
}
@SuppressWarnings("serial")
public class Cube4D extends JFrame//主类继承Frame类{
public paintThread2 pT;//绘图线程
public Cube4D(){
}
public void frame() throws PropertyVetoException//构造函数 {
pT=new paintThread2(this);
this.setResizable(true);
this.setSize(1500, 800);
this.setLocation(300,100);
this.setVisible(true); //显示窗口
pT.start();//绘图线程启动
} boolean open=true,cont=true;
@SuppressWarnings("null") private Image iBuffer;
private Graphics gBuffer;
static double[][] pos;
boolean bo=true;
line fo=new line();
listener pl=new listener();
public void paint (Graphics scr) //重载绘图函数 {
iBuffer=createImage(this.getWidth(),this.getHeight());
gBuffer=iBuffer.getGraphics();
super.paint(gBuffer); if(bo){bo=false;pos=fo.erjinzhi();}
//忽略W轴
if(pl.kc==KeyEvent.VK_LEFT){
fo.turnY(1, pos);
}
if(pl.kc==KeyEvent.VK_RIGHT){
fo.turnY(-1, pos);
}
if(pl.kc==KeyEvent.VK_UP){
fo.turnX(1, pos);
}
if(pl.kc==KeyEvent.VK_DOWN){
fo.turnX(-1, pos);
}
if(pl.kc==KeyEvent.VK_Q){
fo.turnW(1, pos);
}
if(pl.kc==KeyEvent.VK_E){
fo.turnW(-1, pos);
}
//ztrun忽略Z轴
if(pl.kc==KeyEvent.VK_A){
fo.zturnY(1, pos);
}
if(pl.kc==KeyEvent.VK_D){
fo.zturnY(-1, pos);
}
if(pl.kc==KeyEvent.VK_W){
fo.zturnX(1, pos);
}
if(pl.kc==KeyEvent.VK_S){
fo.zturnX(-1, pos);
}
fo.rect(gBuffer,pos);
gBuffer.setColor(this.getBackground());
scr.drawImage(iBuffer,0,0,this);
}
public static void main(final String[] args) throws PropertyVetoException {
Cube4D DB=new Cube4D();//创建主类的对象
DB.frame();
listener p=new listener();
DB.addMouseListener(p);
DB.addMouseMotionListener(p);
DB.addKeyListener(p);
DB.addWindowListener(new WindowAdapter()//添加窗口关闭处理函数 { public void windowClosing(WindowEvent e) { System.exit(0); }});
}}class paintThread2 extends Thread//绘图线程类{ Cube4D DB;
public paintThread2(Cube4D DB) //构造函数 {
this.DB=DB; } @SuppressWarnings("static-access")
public void run()//重载run()函数 {
while(true)//线程中的无限循环
{
DB.repaint();//窗口重绘
}
}
}
关于键盘监控,不多
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
public class listener extends KeyAdapter implements MouseListener,MouseMotionListener{
static char key;
static int kc;
static boolean game2D=false;
Cube4D gm;
line fo=new line();
public void keyPressed(KeyEvent e) {
key=e.getKeyChar();
kc=e.getKeyCode();
if(kc==KeyEvent.VK_SPACE){gm.pos=fo.erjinzhi();}
}
最后附上运行后的图片
我猜这玩意(段代码)还能升维,有兴趣的可以试试。
我为了证明自己是错的,改了几个参数,进行了一次二维升三维,就是分别忽略Z轴进行XY轴的旋转,然后忽略Y轴进行XZ轴的旋转,结果
如图。。。