⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 molecule1.java

📁 包括了JAVA3D(全世界都能看到的网络三维动画)的源代码部分! 很多基础但是却很精彩的例子!有什么不明白的也可以和我交流MSN:guorui0728@hotmail.com
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
// by Liu Peng, Nov.18, 2000

import java.lang.Math.*;
import java.awt.Graphics;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.awt.BorderLayout;
import java.awt.GraphicsConfiguration;
import java.awt.event.WindowAdapter;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.behaviors.mouse.*;
import com.sun.j3d.utils.behaviors.keyboard.*;
import com.sun.j3d.utils.behaviors.picking.*;


public class molecule1 extends Applet implements ActionListener, Runnable {

    Thread timer;
	Transform3D globalTransform3D;
	Transform3D globalTransform3DBackup;
	TransformGroup globalTransformGroup;
	SharedGroup shared;
	boolean timerFlag=true;
	Group group;
  	double radius=0.2; 				
    float angle = 0.0f;
  	int currentLink=0, currentVert=0;
  	int prevLink=0, prevVert=0;
    boolean activateState=true;
    Button activateB = new Button("Stop/Move");
    Button normalB = new Button("Normal");
    Button rotateBX = new Button("RotateX");
    Button rotateBY = new Button("RotateY");
    Button rotateBZ = new Button("RotateZ");
  	
  	class Links_c {
  		double x0, y0, z0;		// 起始坐标
  		int numVert;			// 需要创建的分子数
  		boolean dx,dy,dz;
    		// 如果dx是true,则向X方向扩展;否则向-X方向扩展。dy,dz类似。
  		double probability;
    		// 按dx,dy,dz规定的方向扩展的概率,取值范围必须在[0, 1]之间。
    		// probability取值为0.5时,最易聚簇; 为1或0时,最易散开
    		// 只不过为1时,是按指定的方向散开;为0时,是按相反的方向散开
    		
    	public void init(double ix0,double iy0,double iz0,int inumVert,
    			boolean idx,boolean idy,boolean idz, double iprobability)
    	{
    		x0=ix0; y0=iy0; z0=iz0; numVert=inumVert;
    		dx=idx; dy=idy; dz=idz; probability=iprobability;
    	}
  	};
  	Links_c links[];
  	int numLink;
	Point3d pointPosition[][];
	Transform3D pointTransform3D[][];
	TransformGroup pointTransformGroup[][];



  // 以一种随机和加方向性控制的方式,生成数条分子链的每个分子的坐标
  // 
  private void createVert()
  {
  	double x,y,z, p;
  	boolean dx,dy,dz;
		  	
	// 此处应该和links一起改,否则会出错
  	numLink=3;
  	
  	links =new Links_c[numLink];
  	for (int i=0; i<numLink; i++)
  		links[i] = new Links_c();
  	
  	// 此处应该和numLink一起改,否则会出错
  	links[0].init(-0.5, -0.5, 0.2, 28, false, false, true, 0.6);
	links[1].init(0.6, -0.6, 0, 22, true, true, false, 0.8);
	links[2].init(0, 0.5, -0.2, 26, false, true, false, 0.65);
	pointPosition = new Point3d[numLink][];
  	for (int l=0; l<numLink; l++)
  	{
  		pointPosition[l]=new Point3d[links[l].numVert];
  		for (int i=0; i<links[l].numVert; i++)
  			pointPosition[l][i]=new Point3d();
  		pointPosition[l][0].x=links[l].x0;
  		pointPosition[l][0].y=links[l].y0;
  		pointPosition[l][0].z=links[l].z0;
  	    p=links[l].probability;
  		dx=links[l].dx;
  	    dy=links[l].dy;
  	    dz=links[l].dz;
  	    
  		for (int i=1;i<links[l].numVert;i++)
  		{
			x=Math.random()*radius;
			x=sign(x,p,dx);
			y=Math.sqrt(radius*radius-x*x) * Math.random();
				// Y的值不能也在0-radius范围内随意取值:
				// 因为在X、Y平面上,当X、Y都取radius时,
				// 点(X,Y)就跑到了圆x^2+y^2=r^2的外面了。
				// 所以X、Y坐标必须满足这个约束。
			y=sign(y,p,dy);
			z=Math.sqrt(radius*radius-x*x-y*y);
			z=sign(z,p,dz);
  			pointPosition[l][i].x=pointPosition[l][i-1].x+x;
  			pointPosition[l][i].y=pointPosition[l][i-1].y+y;
  			pointPosition[l][i].z=pointPosition[l][i-1].z+z;
  		}  	
  	}
  }


  // 依次改变所有分子链中每个分子的坐标(每次改一个)
  private void changeAVert()
  {
  	double x,y,z, p;
  	boolean dx,dy,dz;
	
	int l=currentLink;
	int i=currentVert;

	prevLink=l;
	prevVert=i;		  	
  	i++;
  	if (i==links[l].numVert)		// 本条链结束,下次从下条链开始
  	{
  		i=0;
  		l++;
  	}
  	if (l==numLink)			// 所有链结束,重新开始一轮
  	{
  		l=0;
  	}
  	currentLink=l;
  	currentVert=i;

  	p=links[l].probability;
  	dx=links[l].dx;
  	dy=links[l].dy;
  	dz=links[l].dz;

	if (i==0)
	{
  		pointPosition[l][0].x=links[l].x0;
  		pointPosition[l][0].y=links[l].y0;
  		pointPosition[l][0].z=links[l].z0;
  	} else
  	{    
		x=Math.random()*radius;
		x=sign(x,p,dx);
		y=Math.sqrt(radius*radius-x*x) * Math.random();
			// Y的值不能也在0-radius范围内随意取值:
			// 因为在X、Y平面上,当X、Y都取radius时,
			// 点(X,Y)就跑到了圆x^2+y^2=r^2的外面了。
			// 所以X、Y坐标必须满足这个约束。
		y=sign(y,p,dy);
		z=Math.sqrt(radius*radius-x*x-y*y);
		z=sign(z,p,dz);
  		pointPosition[l][i].x=pointPosition[l][i-1].x+x;
  		pointPosition[l][i].y=pointPosition[l][i-1].y+y;
  		pointPosition[l][i].z=pointPosition[l][i-1].z+z;
  	}
  }
	
  private double sign(double v, double p, boolean direction)
  {
  	double ret;
  	if (p>=Math.random())	// 以给定的概率遵照扩展方向的约定
  	{
  		if (direction)
  			ret=v;
  		else
  			ret=-v;
	} else					// 落在规定的概率之外,则与扩展的方向相反
	{
		if (direction)
			ret=-v;
		else 
			ret=v;
	}
	return ret;
  }


  // 将一个坐标系中的任意物体旋向(x,y,z)指定的任意方向(坐标原点不变)
  //
  // 输入:给定旧坐标系中的一点A,它的坐标为(x,y,z)。
  // 输出:两个坐标系之间的转换矩阵(OXYZ-->OX"Y"Z")
  // 要求:旋转后OA为新坐标系中的Y"轴。(如此旋转后,原来与Y轴平行的物体,
  //       将与Y"轴平行,其他位置的物体也将作相应的非扭曲旋转)
  // 旋转方法:
  //    假设OA在ZOX平面的投影为OA'。ZOA'夹角为angle1。则第一步旋转为:
  //       以Y轴为转轴,将ZOX平面旋转angle1度,此时坐标系变为OX'YZ'(A'
  //       处于Z'轴上了);
  //       由于X'垂直于YOZ'平面(X'亦垂直于OA及OA')。假设YOA的夹角为angle2,
  //       则第二步旋转为:以X'为轴,将YOZ'平面旋转angle2度,则此时Y轴与OA
  //       轴重合,记为Y",另外记新的Z坐标为Z",还有X"(是与X'重合的)。
  //       经过上述两次坐标轴旋转,坐标系中的物体也就转向了指定的任意方向。
  private Transform3D transForm(double x, double y,double z)
  {
	double r = Math.sqrt(x*x+y*y+z*z);
	double angle1 = Math.atan(x/z);
	double angle2 = Math.acos(y/r);

//	
//  angle1 调整旋转的角度:	
// 
//  Angle1是从+Z向Z'旋转的实际角度(范围:0-360度),Z'是(x,y,z)点在XOZ平面的投影线。
//        Z        X          Angle1
// ------------------------------------
//    +(or 0)   +(or 0)       angle1             (angle1此时为正)
//    +(or 0)      -        2*PI+angle1          (angle1此时为负)
//        -     +(or 0)      PI+angle1           (angle1此时为负)
//        -        -         PI+angle1           (angle1此时为正)
	double Angle1,Angle2;
	if (z>=0)
	{
		if (x>=0)
			Angle1=angle1;
		else
			Angle1=2*Math.PI+angle1;
	} else
	{
		if (x>=0)
			Angle1=Math.PI+angle1;
		else
			Angle1=Math.PI+angle1;
	}
	

//	
//  angle2 调整旋转的角度:	
//	               
//  Angle2 是从+Y向Z'旋转的实际角度(范围:0-180度)
//        Y         Angle2
// ---------------------------------
//     +(or 0)      angle2                   (angle2此时为正)
//        -         angle2                   (angle2此时为负)
	if (y>=0)
		Angle2=angle2;
	else
		Angle2=angle2;
    			
    Transform3D rot1 = new Transform3D();
    Transform3D rot2 = new Transform3D();
    rot1.rotY(Angle1);
    rot2.rotX(Angle2);

    Transform3D newTransform = new Transform3D();

    newTransform.mul(rot1);
    newTransform.mul(rot2);
    return newTransform;
  }
  


  private Group moleculeLinks()
  {
	group=new Group();

	createVert();

    shared = new SharedGroup();
    shared.addChild(aMolecule());
	pointTransform3D = new Transform3D[numLink][];
	pointTransformGroup = new TransformGroup[numLink][];
  	for (int l=0; l<numLink; l++)
  	{
  		pointTransform3D[l]=new Transform3D[links[l].numVert];
  		pointTransformGroup[l]=new TransformGroup[links[l].numVert];
  		
		for (int i=0;i<links[l].numVert; i++)
		{
			if (i==links[l].numVert-1) 
			{
				pointTransform3D[l][i] = transForm(
					pointPosition[l][i-1].x - pointPosition[l][i].x,
					pointPosition[l][i-1].y - pointPosition[l][i].y,
					pointPosition[l][i-1].z - pointPosition[l][i].z
					);
			} else
			{
				pointTransform3D[l][i] = transForm(
					pointPosition[l][i+1].x - pointPosition[l][i].x,
					pointPosition[l][i+1].y - pointPosition[l][i].y,
					pointPosition[l][i+1].z - pointPosition[l][i].z
					);
			}
			pointTransform3D[l][i].setTranslation(new Vector3d(
				pointPosition[l][i].x, pointPosition[l][i].y, pointPosition[l][i].z));
			pointTransformGroup[l][i] = new TransformGroup(pointTransform3D[l][i]);
			pointTransformGroup[l][i].setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -