📄 molecule2.java
字号:
// by Liu Peng, Dec.15, 2000
import java.lang.Math.*;
import java.awt.Graphics;
import java.applet.Applet;
import java.awt.*;
import java.io.*;
import java.net.URL;
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 com.sun.j3d.utils.image.*;
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.*;
import java.net.*;
import java.util.StringTokenizer;
public class molecule2 extends Applet implements ActionListener, Runnable {
// 下述7个参数由调用者传入
String templateName; // 模板名
String taskName; // 任务名
int totalLink; // 总链数
int lenLink=16; // 每条链的长度
int totalStep; // 总步数
int startStep; // 开始的步号
int stepInterval; // 显示间隔(步长)
int numLinks; // 显示的链数
long curStep; // 当前的显示步号
boolean localFlag=false;
String address;
URL fullUrl;
String site;
int port;
String access;
String servlet="/servlet/template.TAP.RequestData?TaskName=test";
Thread timer;
// 时钟线程
Transform3D globalTransform3D;
Transform3D globalTransform3DBackup;
TransformGroup globalTransformGroup;
SharedGroup shared;
boolean timerFlag=true;
Group group;
float radius=0.2f; // 分子球核心到杆底的距离
// 原始数据的比例调整
double scale=0.2/1; // 1是原始数据中相邻分子核心之间的距离
double scaleX=scale;
double scaleY=scale;
double scaleZ=scale;
boolean debug=false;
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");
int linkDisp[]={5,6,7,9,10,11,12,15}; // 默认要显示的Links
class Links_c {
int linkNum; // 要显示的链的编号(最多显示5条链)
int numVerts; // 每条链的分子数
};
Links_c links[];
Point3d pointPosition[][];
Transform3D pointTransform3D[][];
TransformGroup pointTransformGroup[][];
StringTokenizer st=null;
String message=null;
public void init(){
// 获取本Applet执行的IP地址
fullUrl=getCodeBase();
if (fullUrl==null)
{
localFlag=true;
debug=true;
err("Can't getCodeBase(), used direct address: 192.168.166.253");
address="http://192.168.166.253/servlet/template.TAP.RequestData?TaskName=test";
} else
{
site=new String();
site=fullUrl.getHost();
port=fullUrl.getPort();
if (port!=-1)
{
access="http://"+site+":"+port;
} else
{
access="http://"+site;
}
address=access+servlet;
}
// 获取Html调用者传入的参数
templateName=getParameter("TemplateName");
if (templateName==null)
{
templateName="template.TAP.RequestData";
}
taskName=getParameter("TaskName");
if (taskName==null)
{
taskName="test";
}
String s=getParameter("NChains");
if (s==null)
{
totalLink=50;
} else
{
totalLink=Integer.parseInt(s);
}
s=getParameter("LChains");
if (s==null)
{
lenLink=16;
} else
{
lenLink=Integer.parseInt(s);
}
s=getParameter("Count");
if (s==null)
{
totalStep=200;
} else
{
totalStep=Integer.parseInt(s);
}
s=getParameter("StartStep");
if (s==null)
{
startStep=402;
} else
{
startStep=Integer.parseInt(s);
}
curStep=startStep;
s=getParameter("StepInterval");
if (s==null)
{
stepInterval=2;
} else
{
stepInterval=Integer.parseInt(s);
}
}
public void myShow(String s){
(new Frame(s)).show();
}
void err(String msg)
{
myShow(msg);
}
void msg(String msg)
{
if (debug) System.out.print(msg);
}
void msgln(String msg)
{
if (debug) System.out.println(msg);
}
// 根据调用本Applet传入的参数,初始化Links的有关参数
private void initLinks()
{
// 以下参数可以从浏览器上由用户交互指定
numLinks=3;
// ........需要根据参数修改
links =new Links_c[numLinks];
pointPosition = new Point3d[numLinks][];
for (int l=0;l<numLinks; l++)
{
links[l] = new Links_c();
links[l].linkNum=linkDisp[l];
// ........需要根据参数修改
links[l].numVerts=lenLink;
// ........需要根据参数修改
pointPosition[l]=new Point3d[links[l].numVerts];
for (int i=0; i<links[l].numVerts; i++)
pointPosition[l][i]=new Point3d();
}
}
// 读入每条分子链的每个分子的坐标
//
private boolean readAScene()
{
boolean flag=true;
try
{
String url=address+"&Step="+curStep+"&nLink="+numLinks;
for (int l=0;l<numLinks;l++)
{
url=url+"&Link"+l+"="+links[l].linkNum;
}
msgln(url);
URL u=new URL(url);
URLConnection con=u.openConnection();
InputStream istream=con.getInputStream();
BufferedReader br=new BufferedReader(new InputStreamReader(istream));
st = new StringTokenizer(br.readLine(),",",false);
long step=Long.parseLong(st.nextToken());
String m;
// 服务器返回的Step数据
if (step!=curStep)
{
msgln("Error data returned from webserver! Code: 01");
} else
{
m="step="+step;
msg(m);
}
int num=Integer.parseInt(st.nextToken());
// 服务器返回的链的数量数据
if (num!=numLinks)
{
msgln("Error data returned from webserver! Code: 03");
} else
{
m=" numLinks="+num;
msgln(m);
}
for (int l=0; l<numLinks;l++)
{
// 服务器返回的链的编号数据
int n=Integer.parseInt(st.nextToken());
m="link="+n;
msgln(m);
if (n!=links[l].linkNum)
{
msgln("Error data returned from webserver! Code: 06");
}
for (int i=0;i<links[l].numVerts; i++)
{
// 获取X座标
double x=Double.parseDouble(st.nextToken());
m=" x="+x;
msg(m);
pointPosition[l][i].x=x*scaleX;
// 获取Y座标
double y=Double.parseDouble(st.nextToken());
m=" y="+y;
msg(m);
pointPosition[l][i].y=y*scaleY;
// 获取Z座标
double z=Double.parseDouble(st.nextToken());
m=" z="+z;
msgln(m);
pointPosition[l][i].z=z*scaleZ;
} // end for molecule
} // end for links
istream.close();
curStep = curStep+stepInterval;
if (curStep >= startStep+totalStep*stepInterval)
curStep=startStep; // 一个轮回,一元复始
} // end Try
catch(IOException e) {
e.printStackTrace();
message = e.toString();
msgln("====================================================");
msgln(message);
flag=false;
}
return flag;
}
// 将一个坐标系中的任意物体旋向(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
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -