📄 clothsim.java
字号:
import java.awt.AWTEvent;
import java.util.Enumeration;
import java.applet.Applet;
import java.lang.Math.*;
import java.awt.Graphics;
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 com.sun.j3d.utils.geometry.Box;
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 com.sun.j3d.utils.image.TextureLoader;
//添加类包
/////////////////////////////////////////////////////////////
// ClothSim主类 //
// //
// 1.创建场景图,添加鼠标,键盘行为,添加光照背景, //
// 创建ClothSimFace面模型 //
// 2. 初始质点位置,速度. //
// 3.创建刷新线程,调用物理模型计算,刷新质点坐标, //
// 调用lothSimUpdater类,刷新三角面的位置,顶点法向量 //
// //
// //
/////////////////////////////////////////////////////////////
public class ClothSim extends Applet implements Runnable
{
ClothSim clothSim;
Thread timer;//声明一个刷新线程对象
boolean timerFlage=true;//刷新线程暂停标志
int timerFlagevcout=0;//键盘响应线程状态切换变量
Point3d pointPosition[][];//声明质点位置三维坐标数组
Transform3D pointTransform3D[][];//声明质点局部坐标系Transform3D数组
TransformGroup pointTransformGroup[][];//声明质点局部坐标系数组
SharedGroup shared;//声明一个复制SharedGroup对象
Vector3d vectorABack[][];//声明质点加速度备用数组
Point3d pointPositionBack[][];//声明质点位置三维坐标备用数组
Vector3d vectorVBack[][];//声明质点速度备用数组
Vector3d pointNormal[][];//质点法向量数组
Vector3d vector3dV[][];//声明质点速度数组
Physics physicsActive;//声明一个物理模型对象
Vector3d vectorF[][];//声明质点受力对象
TriangleArray clothSimArray=null;//声明ClothSimFace面模型对象
LineArray clothSimLines= null;//声明ClothSImLines线模型对象
GeometryUpdater geometryUpdater=null;//声明GeometryUpdater更新对象
GeometryUpdater geometryLineUpdater=null;//声明GeometryLineUpdater更新对象
private java.net.URL texImage = null;//地面纹理图片链接变量
private java.net.URL bgImage = null;//背景贴图图片链接变量
boolean downFlage=false;//布料脱离旗杆标志位
double xyDistance=0.06;//相邻质点距离
public Switch s;//面,线模型Switch对象
public Switch sPoint;//质点球模型Switch对象
double k=500.0;//弹性模量常数
double kair=0.0125;//空气阻力常数
double kvi=0.5;//空气流参数
double lbend=xyDistance*2;//弯曲弹簧原始长度常数
double lstretch=xyDistance;//结构弹簧原始长度常数
double lshear=xyDistance*Math.sqrt(2.0);//剪切弹簧原始长度常数
double mg=0.033516*20;//质点重量常数
double m=0.00342*20;//质点质量常数
double t=0.003;//位置数组pointPosition刷新计算时间常数
double Fwindx=2.5;//x方向风力变量初始值
double Fwindz=-1.5;//z方向风力变量初始值
int clothSimFaceType=1;//clothsim面形式变量
int tWait=2;//刷新线程刷新间隔时间变量
int xTotal=16;//横向质点总数
int yTotal=12;//纵向质点总数
int ouLaFlage=0;//在简单欧拉公式和改进欧拉公式间切换的标志位
BranchGroup objRoot;
int h=0;
SimpleUniverse u ;
TransformGroup objTrans;
TransformGroup trans1;
//创建场景图
public BranchGroup createSceneGraph(SimpleUniverse su)
{
objRoot=new BranchGroup();
objRoot.setCapability(BranchGroup.ALLOW_DETACH);
objTrans=new TransformGroup();
objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
objTrans.setCapability(Group.ALLOW_CHILDREN_EXTEND);
//创建根节点对象,以及根节点坐标系
Transform3D trans3D1=new Transform3D();
trans3D1.setTranslation(new Vector3f(-1.0f,0.0f,0.0f));
trans1=new TransformGroup(trans3D1);
trans1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
trans1.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
trans1.addChild(objTrans);
objRoot.addChild(trans1);
//创建旗杆,布料整体局部坐标系
//objRoot.removeChild(trans1);
Group clothSimArray=ClothSimArray();
//创建clothSim质点球模型
ClothSimFace clothSimFace = new ClothSimFace();
//创建clothSim三角面模型
ClothSimLine clothSimLines=new ClothSimLine();
//创建clothSim线模型
s=new Switch();
s.setCapability(Switch.ALLOW_SWITCH_READ );
s.setCapability(Switch.ALLOW_SWITCH_WRITE );
s.addChild(clothSimFace);
s.addChild(clothSimLines);
s.setWhichChild(0);
//创建线,面模型Switch对象,并设置其能力
sPoint=new Switch();
sPoint.setCapability(Switch.ALLOW_SWITCH_READ);
sPoint.setCapability(Switch.ALLOW_SWITCH_WRITE );
sPoint.addChild(clothSimArray);
sPoint.setWhichChild(Switch.CHILD_NONE);
//创建质点球模型Switch对象,并设置其能力
objTrans.addChild(s);
objTrans.addChild(sPoint);
//将Switch对象s,sPoint添加到objTrans对象
ColoringAttributes ca=new ColoringAttributes();
ca.setColor(0.1f,0.4f,0.4f);
Appearance app=new Appearance();
app.setColoringAttributes(ca);
Cylinder clothSimCylinder=new Cylinder(0.015f,2.0f,app);
objTrans.addChild(clothSimCylinder);
Transform3D trans3DShpere=new Transform3D();
trans3DShpere.setTranslation(new Vector3f(0.0f,1.025f,0.0f));
TransformGroup transShpere=new TransformGroup(trans3DShpere);
objTrans.addChild(transShpere);
Sphere shpere=new Sphere(0.03f,app);
transShpere.addChild(shpere);
//添加旗杆
BoundingSphere bounds =
new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
TextureLoader bgTexture = new TextureLoader(bgImage, this);
Background bg = new Background(bgTexture.getImage());
bg.setApplicationBounds(bounds);
objRoot.addChild(bg);
//添加背景
Appearance app1 = new Appearance();
Material material = new Material();
material.setEmissiveColor(new Color3f(0.0f,0.5f,0.3f));
app1.setMaterial(material);
app1.setCapability(app.ALLOW_COLORING_ATTRIBUTES_WRITE);
TextureLoader myLoader1=new TextureLoader (texImage,this);
ImageComponent2D myImage1=myLoader1.getImage ();
if ( myImage1 == null )
{
System.err.println( "Cannot load texture '" + texImage + "'" );
return null;
}
Texture2D myTex=(Texture2D)myLoader1.getTexture();
app1.setTexture(myTex);
Transform3D trans3DShpere1=new Transform3D();
trans3DShpere1.setTranslation(new Vector3f(0.0f,-1.0f,0.0f));
TransformGroup transShpere1=new TransformGroup(trans3DShpere1);
objTrans.addChild(transShpere1);
Box box=new Box(100f,0.005f,100.0f,Box.GENERATE_TEXTURE_COORDS,app1);
transShpere1.addChild(box);
//创建地面并添加纹理
// 添加鼠标行为
MouseRotate myMR = null;
MouseTranslate myMT = null;
MouseZoom myMZ = null;
// 添加旋转功能
myMR = new MouseRotate();
myMR.setTransformGroup(objTrans);
myMR.setSchedulingBounds(new BoundingSphere());
objRoot.addChild(myMR);
// 添加平移功能
myMT = new MouseTranslate();
myMT.setTransformGroup(objTrans);
myMT.setSchedulingBounds(new BoundingSphere());
objRoot.addChild(myMT);
// 添加缩放功能
myMZ = new MouseZoom();
myMZ.setTransformGroup(objTrans);
myMZ.setSchedulingBounds(new BoundingSphere());
objRoot.addChild(myMZ);
//添加键盘响应功能
ClothSimBehavior myClothSimBehavior = new ClothSimBehavior();
myClothSimBehavior.setSchedulingBounds(new BoundingSphere());
// 设定作用范围
objRoot.addChild(myClothSimBehavior);
// 将键盘响应对象添加到根结点
AmbientLight lightA = new AmbientLight();
lightA.setInfluencingBounds(new BoundingSphere(new Point3d(),1000.0));
objRoot.addChild(lightA);
DirectionalLight lightD1 = new DirectionalLight();
lightD1.setInfluencingBounds(new BoundingSphere(new Point3d(),1000.0));
Vector3f direction = new Vector3f(0.25f, 0.0f, -1.0f);
Color3f color = new Color3f(1.0f,1.0f,1.0f);
direction.normalize();
lightD1.setDirection(direction);
lightD1.setColor(color);
objRoot.addChild(lightD1); //添加正面光照
DirectionalLight lightD2 = new DirectionalLight();
lightD2.setInfluencingBounds(new BoundingSphere(new Point3d(),1000.0));
Vector3f direction2 = new Vector3f(0.5f, 0.0f, 1.0f);
Color3f color2 = new Color3f(1.0f,0f,0f);
direction2.normalize();
lightD2.setDirection(direction2);
lightD2.setColor(color2);//添加反面光照
objRoot.addChild(lightD2);
//添加光照
objRoot.compile();
return objRoot;
}
//ClothSim主类构造函数
public ClothSim() {
}
public ClothSim(java.net.URL bgurl, java.net.URL texurl) {
bgImage = bgurl;
texImage = texurl;
}
public void init() {
if (bgImage == null) {
try {
bgImage = new java.net.URL(getCodeBase().toString() +
"bg.jpg");
}
catch (java.net.MalformedURLException ex) {
System.out.println(ex.getMessage());
System.exit(1);
}
}
if (texImage == null) {
try {
texImage = new java.net.URL(getCodeBase().toString() +
"apimage.jpg");
}
catch (java.net.MalformedURLException ex) {
System.out.println(ex.getMessage());
System.exit(1);
}
}
//导入背景,地面纹理图片
initializationPVF();//初始质点受力,速度
physicsActive=new Physics();//创建质点物理模型对象
setLayout(new BorderLayout());
Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
add("Center", c);
Viewer viewer = new Viewer(c);
Vector3d viewpoint = new Vector3d(0.0, 0.0, 4.0); //初始观察点位置
Transform3D t = new Transform3D();
t.set(viewpoint);
ViewingPlatform v = new ViewingPlatform( );
v.getViewPlatformTransform().setTransform(t);
u = new SimpleUniverse(v, viewer);
BranchGroup scene = createSceneGraph(u);
u.getViewingPlatform();
u.addBranchGraph(scene);
}
// 根据物理模型不断刷新质点位置线程
public void start()
{
timer = new Thread(this);
timer.start();
}
//线程run函数
public void run()
{
while (true)
{
try{
if(h==1)
{
objRoot.addChild(trans1);
h=0;}
else
if(timerFlage==true){
physicsActive.oulaCalculate();//根据质点的受力,利用简单欧拉公式和改进欧拉公式混合计算刷新质点位置
UpdataerLineArray();//刷新质点球模型
clothSimLines.updateData(geometryLineUpdater); //刷新线模型
clothSimArray.updateData(geometryUpdater);//刷新三角面模型
Thread.sleep(tWait);
} } catch (InterruptedException e) {return;}
}
}
//实例化类ClothSim主函数
public static void main(String[] args)
{ java.net.URL bgurl = null;
java.net.URL texurl = null;
try {
bgurl = new java.net.URL("file:bg.jpg");
texurl = new java.net.URL("file:apimage.jpg");
}
catch (java.net.MalformedURLException ex) {
System.out.println(ex.getMessage());
System.exit(1);
}//创建背景,地面纹理链接
new MainFrame(new ClothSim(bgurl, texurl),2000,1000);
}
//初始质点位置坐标,速度,受力
public void initializationPVF()
{
pointPosition=new Point3d[xTotal][yTotal];
vector3dV=new Vector3d[xTotal][yTotal];
vectorF=new Vector3d[xTotal][yTotal];
vectorABack=new Vector3d[xTotal][yTotal];
vectorVBack=new Vector3d[xTotal][yTotal];
pointPositionBack =new Point3d[xTotal][yTotal];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -