[Bprocessor-commit] bprocessor/src/net/sourceforge/bprocessor/packages/physics PhysicsSurface.java
Status: Pre-Alpha
Brought to you by:
henryml
From: Sebastian G. <sg...@us...> - 2011-05-16 06:11:07
|
Update of /cvsroot/bprocessor/bprocessor/src/net/sourceforge/bprocessor/packages/physics In directory vz-cvs-2.sog:/tmp/cvs-serv11353/src/net/sourceforge/bprocessor/packages/physics Added Files: PhysicsSurface.java PhysicsNet.java PhysicsPlane.java PhysicsSpring.java PhysicsParticle.java PhysicsPackage.java Log Message: Hanging Chain Tools, Volume Calc --- NEW FILE: PhysicsSpring.java --- package net.sourceforge.bprocessor.packages.physics; import net.sourceforge.bprocessor.model.Vertex; //import net.sourceforge.bprocessor.model.plugin.PhysicsParticle; public class PhysicsSpring { //properties PhysicsParticle pA; //Particle at one end of the spring PhysicsParticle pB; //Particle at other end of the spring double startL; //original starting length of Spring (generated from b-net) double eql; //equilibrium length of the spring double l; //actual length of the spring double lLast; //last length of the spring double c; //spring constant double sf; //force value double sf_damped; //force value double restLengthFactor;//global factor - eql length in relation to cNet edge length double restLengthScale; //local scaling of restlength (unique to spring) Vertex fA; //force of the spring acting on Particle A Vertex fB; //force of the spring acting on Particle B //Constructor PhysicsSpring(PhysicsParticle pA, PhysicsParticle pB, double eql, double c) { this.pA = pA; this.pB = pB; this.eql = eql; this.c = c; this.l = getLength(); this.startL = this.l; lLast = l; sf = 0; sf_damped = 0; fA = new Vertex(0,0,0); fB = new Vertex(0,0,0); pA.connectSpring(this); pB.connectSpring(this); sf=0; sf_damped = 0; restLengthScale = 1.0; } //compute current length of spring double getLength() { double sl; sl = pA.pos.distance(pB.pos); return sl; } //compute current damping factor double calcDamping(double time, double spring_damping) { double damping; //damping = v * spring_d = (distance / time) * spring_d damping = (l-lLast)*spring_damping / time; lLast = l; return damping; } //compute spring force void calcForce(double time, double spring_damping) { sf = (l-(eql*restLengthFactor*restLengthScale))*c; sf_damped = sf + calcDamping(time, spring_damping); //get Vector from A to B and vice versa fA = pB.pos.minus(pA.pos); fB = pA.pos.minus(pB.pos); //normalize force Vectors fA.normalize(); fB.normalize(); //scale force Vectors to force value fA.scaleIt(sf_damped); fB.scaleIt(sf_damped); } void update(double time, double spring_damping) { l = getLength(); calcForce(time, spring_damping); } } --- NEW FILE: PhysicsParticle.java --- package net.sourceforge.bprocessor.packages.physics; import net.sourceforge.bprocessor.model.Vertex; import java.util.*; public class PhysicsParticle { //properties Vertex pos; //position Vertex nPos; // new position Vertex vel; //velocity Vertex a; //acceleration double m; //mass Vertex f; //force acting on particle boolean fix; //fix or movable particle? int ID; //Particle ID for identification Vertex aForce; //additional force - sum of other calculations. Is added to acceleration calculation. Vertex lastPos; //last position of vertex ArrayList<PhysicsSpring> springs = new ArrayList(); //springs connected to particle //constructor PhysicsParticle (Vertex node, Vertex velocity, Vertex acceleration, double mass, int ID) { pos = node; vel = velocity; a = acceleration; m = mass; fix = node.isCorner(); nPos = new Vertex(pos.getX(),pos.getY(),pos.getZ()); this.ID = ID; aForce = new Vertex(0,0,0); lastPos = nPos; } //add a spring connected to Particle void connectSpring(PhysicsSpring s) { springs.add(s); } //add force void addForce(Vertex force) { aForce = aForce.add(force); } //calculate acceleration void calcAcc(double gravity, double particle_drag) { f = new Vertex(0,0,0); //spring forces for (int i = 0; i<springs.size(); i++) { PhysicsSpring s = (PhysicsSpring) springs.get(i); //check paricles of force if (ID == s.pA.ID) { f=f.add(s.fA); } else { f=f.add(s.fB); } } //gravity f = f.add(new Vertex(0,0,gravity*m)); //any other force f = f.add(aForce); aForce = new Vertex(0,0,0); //coefficient of drag, damping //f = v * -coefficient of damping f = f.add(vel.scale(-1*particle_drag)); //acceleration a=f.scale(1.0/m); } //move particle void move(double time, double gravity, double particle_drag) { if ((fix == false) && (pos.isCorner() != true)) { nPos = new Vertex(pos.getX(),pos.getY(),pos.getZ()); //calculate acceleration calcAcc(gravity, particle_drag); //calculate new position //pos new = pos old + vel * time + 0.5 * acceleration * time * time nPos = nPos.add(vel.scale(time)); nPos = nPos.add(a.scale(0.5*time*time)); //calculate new velocity //vel = acceleration * time vel = vel.add(a.scale(time)); lastPos = nPos; } } } --- NEW FILE: PhysicsSurface.java --- package net.sourceforge.bprocessor.packages.physics; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.*; import com.sun.net.ssl.internal.ssl.Debug; import net.sourceforge.bprocessor.model.Edge; import net.sourceforge.bprocessor.model.Space; import net.sourceforge.bprocessor.model.Vertex; import net.sourceforge.bprocessor.model.Surface; public class PhysicsSurface { Surface bSurf; //the original bNet Surface PhysicsPlane avPlane; //average Plane of Surface HashMap<Vertex,PhysicsParticle> particles = new HashMap(); //maps the surface vertices to the corresponding particles HashMap<Edge,PhysicsSpring> springs = new HashMap(); //maps the surface edges to the corresponding springs HashMap<Vertex, Double> lastPlaneDist = new HashMap(); //maps the surface vertices to their last average plane distance double lastLength; double lastDiaLength; //constructors PhysicsSurface (Surface bNetSurface, HashMap<Vertex,PhysicsParticle> VPmap, HashMap<Edge,PhysicsSpring> ESmap) { bSurf = bNetSurface; particles = VPmap; springs = ESmap; List<Edge> edges = bSurf.getEdges(); //get current average length double l = 0; for (Edge e : edges) { l += e.getLength(); } l = l/edges.size(); lastLength = l; //get current average diagonal length double dl = 0; List<Vertex> vertices = bSurf.getVertices(); if (vertices.size() == 4) { dl = vertices.get(0).distance(vertices.get(2)) + vertices.get(1).distance(vertices.get(3)); dl = dl / 2; } lastDiaLength = dl; for (Vertex v : vertices) { lastPlaneDist.put(v,new Double(0)); } } void equalizeEdges(double time, double spring_constant, double damping) { List<Edge> edges = bSurf.getEdges(); //get average (desired) edge length double l = 0; for (Edge e : edges) { l += e.getLength(); } l = l/edges.size(); for (Edge e : edges) { //calculate force on particles using spring equation incl. damping double sf = (l-e.getLength())*spring_constant; sf = sf + ((l-lastLength)*damping / time); lastLength = l; //get Vector from A to B and vice versa Vertex fB = e.getTo().minus(e.getFrom()); Vertex fA = e.getFrom().minus(e.getTo()); //normalize force Vectors fA.normalize(); fB.normalize(); //scale force Vectors to force value fA.scaleIt(sf); fB.scaleIt(sf); //add forces to corresponding particles PhysicsParticle pA = particles.get(e.getFrom()); PhysicsParticle pB = particles.get(e.getTo()); pA.addForce(fA); pB.addForce(fB); } } Vertex averageNormal() { bSurf.calcNormals(); return bSurf.normal(); /* //* @Michael: algorithm for Normal seems to be so complicated... why? Vertex nV = new Vertex(0,0,0); List<Vertex> vertices = bSurf.getVertices(); double num = vertices.size(); if (num>3) { //if surface has more than 3 vertices //add first two vertices to the end of the list for loop vertices.add(vertices.get(0)); vertices.add(vertices.get(1)); for (int i=0; i<num; i++) { Vertex a = vertices.get(0).minus(vertices.get(1)); Vertex b = vertices.get(2).minus(vertices.get(1)); Vertex n = a.cross(b); n.normalize(); nV = nV.add(n); } nV.normalize(); } if (num == 3) { //surface is triangular - there is only one normal Vertex a = vertices.get(0).minus(vertices.get(1)); Vertex b = vertices.get(2).minus(vertices.get(1)); nV = nV.add(a.cross(b)); //nV = nV.scale(1/3); nV.normalize(); } return nV; */ } double calcArea() { double area = 0.0; List<Vertex> vertices = bSurf.getVertices(); double num = vertices.size(); vertices.add(vertices.get(0)); List<Vertex> crossProducts = new ArrayList<Vertex>(); for (int i=0; i<num; i++) { Vertex p1 = vertices.get(i); Vertex p2 = vertices.get(i+1); Vertex cP = p1.cross(p2); crossProducts.add(cP); } Vertex sum = new Vertex(0,0,0); for (Vertex cP : crossProducts) { sum = sum.add(cP); } double dotP; dotP = Math.abs(averageNormal().dot(sum)); area = 0.5 * dotP; return area; } void normalForce(Space guides, double time, double force) { List<Vertex> vertices = bSurf.getVertices(); Vertex n = averageNormal(); n.normalize(); n = n.scale(force); //display force vector Vertex c = bSurf.center(); Edge eA = new Edge(c,c.add(n)); guides.add(eA); for (Vertex v : vertices) { //get corresponding Particle PhysicsParticle pA = particles.get(v); //add force to particle pA.addForce(n); } } void planarize(Space guides, double time, double spring_constant, double spring_damping) { if (spring_constant!=0) { List<Vertex> vertices = bSurf.getVertices(); avPlane = new PhysicsPlane(averageNormal(),bSurf.center()); //vertices.get(0)); for (Vertex v : vertices) { //get corresponding Particle PhysicsParticle pA = particles.get(v); //get vector to average plane Vertex nV = avPlane.PointNormalToPlane(v); //calculate spring force and damping double pl = nV.length(); double lastPl = (double) lastPlaneDist.get(v); double sf = (pl)*spring_constant; sf = sf + ((pl-lastPl)*spring_damping / time); //save current length for next calculation lastPlaneDist.put(v, new Double(pl)); //add force to particle nV.normalize(); nV = nV.scale(sf); pA.addForce(nV); //display force vector Edge eA = new Edge(v,avPlane.PointProjectToPlane(v)); guides.add(eA); } } } void quadToRect(Space guides, double time, double spring_constant, double spring_damping) { //make a quad surface rectangular by equalizing the length of both diagonals List<Vertex> vertices = bSurf.getVertices(); //these forces are only applied if surface is quad if (vertices.size() == 4) { //create List of diagonals ArrayList<Edge> dEdges = new ArrayList<Edge>(); Edge eA = new Edge(vertices.get(0), vertices.get(2)); guides.add(eA); dEdges.add(eA); Edge eB = new Edge(vertices.get(1), vertices.get(3)); guides.add(eB); dEdges.add(eB); //get average diagonal length double dl = (eA.getLength() + eB.getLength()) / 2; //add spring forces to diagonals for (Edge e : dEdges) { //calculate force on particles using spring equation incl. damping double sf = (dl-e.getLength())*spring_constant; sf = sf + ((dl-lastDiaLength)*spring_damping / time); lastDiaLength = dl; //get Vector from A to B and vice versa Vertex fB = e.getTo().minus(e.getFrom()); Vertex fA = e.getFrom().minus(e.getTo()); //normalize force Vectors fA.normalize(); fB.normalize(); //scale force Vectors to force value fA.scaleIt(sf); fB.scaleIt(sf); //add forces to corresponding particles PhysicsParticle pA = particles.get(e.getFrom()); PhysicsParticle pB = particles.get(e.getTo()); pA.addForce(fA); pB.addForce(fB); } } } } --- NEW FILE: PhysicsPackage.java --- package net.sourceforge.bprocessor.packages.physics; import net.sourceforge.bprocessor.gl.Editor; import net.sourceforge.bprocessor.gl.tool.AbstractTool; import net.sourceforge.bprocessor.model.Command; import net.sourceforge.bprocessor.model.Edge; import net.sourceforge.bprocessor.model.Geometric; import net.sourceforge.bprocessor.model.Item; import net.sourceforge.bprocessor.model.Operation; import net.sourceforge.bprocessor.model.Space; import net.sourceforge.bprocessor.model.Vertex; import net.sourceforge.bprocessor.model.Surface; import net.sourceforge.bprocessor.model.plugin.NetCommand; import net.sourceforge.bprocessor.packages.physics.PhysicsNet; import net.sourceforge.bprocessor.packages.skeleton.SkeletonPackage.SkeletonTool; import java.awt.event.MouseEvent; import java.util.*; /* * To Do * Michael: * parameters additional parameters should be saved when added, change function , the display of the value is not automatically updated. * Plugin Parameters and Selection Parameters: they should not be displayed in the same panel. Rather split the existing panel. So there can be a selection and a tool running at the same time and all information is visible. * Sliders, Checkboxes, etc. for the plugin controls * A plugin button should be able to run a tool with a selection / mouse interaction. * * Modify new net while simulation is running, i.e. corner property, etc. * Planarity and regularity of panels, add bending stiffness! * Rectangularity needs improvement, bending stiffness! * Add parameters to b-net and save them! - see above, Michael, add and save parameters to original net * Subdivision * Selection => parameter changes to vertices and edges, not only global * Volume calculation and inflation force * Auto-detect corners of net (vertices that are only connected to 2 edges) * time settings and parameters */ public class PhysicsPackage { public static class Springsystem extends NetCommand { private physicsChangeSpringTool changeSpringTool; private physicsChangeWeightTool changeWeightTool; Space union; //Union containing Objects created by script Space cNet; //copy of b-Net, graphical representation of Physics Net PhysicsNet pN; //Physics Net = Simulation Object HashMap<Edge, Edge> edges = new HashMap(); HashMap<Vertex, Vertex> vertices = new HashMap(); //parameters double gravity; double mass; double pDamp; double cDamp; double restLengthFactor; double springConstant; double equalConstant; double equalDamping; double rectConstant; double rectDamping; double planeConstant; double planeDamping; //double normalForce; double volume; //boolean editNet; public void initialize(Space net) { //parameters gravity = -9.81; parameters.put("Gravity [m/s2]", gravity); mass = 1; parameters.put("Particle Mass [kg]", mass); pDamp = 2.0; parameters.put("Particle Damping [N sec/m]",pDamp); cDamp = 2.0; parameters.put("Spring Damping [N sec/m]",cDamp); restLengthFactor = 0.5; parameters.put("Spring Restlength Factor",restLengthFactor); springConstant = 20.0; parameters.put("Spring Constant c [N/m]",springConstant); equalConstant = 0.0; parameters.put("Equal Edges Spring Constant ec [N/m]",equalConstant); equalDamping = 2.0; parameters.put("Equal Edges Damping [N sec/m]", equalDamping); rectConstant = 0.0; parameters.put("Equal Diagonals Spring Constant rc [N/m]",rectConstant); rectDamping = 2.0; parameters.put("Equal Diagonals Damping [N sec/m]", rectDamping); planeConstant = 0.0; parameters.put("Planarity Spring Constant pc [N/m]",planeConstant); planeDamping = 2.0; parameters.put("Planarity Damping [N sec/m]", planeDamping); //normalForce = 0.0; //parameters.put("Normal Surface Force [N]", normalForce); volume = 1.0; parameters.put("Volume [m3]", volume); //editNet = true; //parameters.putBoolean("Edit B-Net", editNet); super.initializeNoItem(net); //create copy of b-Net Map map = new HashMap(); //map = net.getOwnParameters(); cNet = net.copy(map); cNet.setName(net.getName()+"- Physics Net"); //cNet.edit(); //copy corner points Collection<Vertex> nVertices = net.getVertices(); Collection<Vertex> cVertices = cNet.getVertices(); for (Vertex nV : nVertices) { for (Vertex cV : cVertices) { if (nV.coincides(cV)) { cV.setCorner(nV.isCorner()); vertices.put(nV,cV); } } } //create Edges HashMap Collection<Edge> nEdges = net.getEdges(); Collection<Edge> bEdges = cNet.getEdges(); for (Edge nE : nEdges) { for (Edge cE : bEdges) { if (nE.equivalent(cE)) { edges.put(nE,cE); } } } //create physics Net pN = new PhysicsNet(cNet, gravity, springConstant, cDamp, pDamp, mass, restLengthFactor); //tools changeSpringTool = new physicsChangeSpringTool(cNet,pN,edges); parameters.put("Change Spring Restlength", new Operation() { @Override public void perform() { System.out.println("activate tool"); cNet.edit(); Editor.instance().changeTool(changeSpringTool); } }); changeWeightTool = new physicsChangeWeightTool(pN); parameters.put("Change Particle Weight", new Operation() { @Override public void perform() { System.out.println("activate tool"); cNet.edit(); Editor.instance().changeTool(changeWeightTool); } }); } public void evaluate() { //remove all elements of last iteration //clear(); ////////////////////////////////////////////////////////////////// //get changed parameters //gravity gravity = (Double) parameters.getDouble("Gravity [m/s2]"); pN.gravity = gravity; //particle Mass double oldMass = mass; mass = (Double) parameters.getDouble("Particle Mass [kg]"); if (mass!=oldMass) { pN.updateMass(mass); } //particle Damping pDamp = (Double) parameters.getDouble("Particle Damping [N sec/m]"); pN.particle_d =pDamp; //spring damping cDamp = (Double) parameters.getDouble("Spring Damping [N sec/m]"); pN.spring_d = cDamp; //spring restlength factor restLengthFactor = (Double) parameters.getDouble("Spring Restlength Factor"); //spring constant Double oldSpringConstant = springConstant; springConstant = (Double) parameters.get("Spring Constant c [N/m]"); if (oldSpringConstant!=springConstant) { pN.updateSpringConstant(springConstant); } //equal edges parameters equalConstant = (Double) parameters.get("Equal Edges Spring Constant ec [N/m]"); equalDamping = (Double) parameters.get("Equal Edges Damping [N sec/m]"); //rectangular quads parameters rectConstant = (Double) parameters.get("Equal Diagonals Spring Constant rc [N/m]"); rectDamping = (Double) parameters.get("Equal Diagonals Damping [N sec/m]"); //Planarity planeConstant = (Double) parameters.get("Planarity Spring Constant pc [N/m]"); planeDamping = (Double) parameters.get("Planarity Damping [N sec/m]"); //normal Force //normalForce = (Double) parameters.get("Normal Surface Force [N]"); //boolean parameters //editNet = (Boolean) parameters.getBoolean("Edit B-Net"); //Desired Volume volume = (Double) parameters.get("Volume [m3]"); ///////////////////////////////////////////////////////////////////////////////////////////// //track changes of bNet and modify Physics Net accordingly //update vertices Collection<Vertex> bVertices = net.getVertices(); for (Vertex bV : bVertices) { if (bV.isCorner()) { Vertex pV = vertices.get(bV); pV.setX(bV.getX()); pV.setY(bV.getY()); pV.setZ(bV.getZ()); pN.updatePos(pV); } } //update edges Collection<Edge> bEdges = net.getEdges(); for (Edge bE : bEdges) { pN.updateRestLength(edges.get(bE), bE.getLength()); pN.setRestLengthFactor(edges.get(bE), restLengthFactor); } //add a union space containing all new elements union = (Space) net.getOwner().find("PhysicsSystem"); //check if space was already created if (union == null) { union = Item.createUnion("PhysicsSystem"); net.getOwner().add(union); } else { union.clear(); } //add guidelines Space guides = Item.createUnion("Guidelines"); union.add(guides); //change p-net /*if (editNet) { net.edit(); } else { cNet.edit(); }*/ pN.update(guides, 0.02, equalConstant, equalDamping, rectConstant, rectDamping, planeConstant, planeDamping, volume); union.add(cNet); } public String title() { return "Springsystem"; } } public PhysicsPackage() { Command.register(Springsystem.class); } //Tool public static class physicsChangeSpringTool extends AbstractTool { Space cNet; //copy of b-Net, graphical representation of Physics Net PhysicsNet pN; //Physics Net = Simulation Object HashMap<Edge, Edge> edges = new HashMap(); public physicsChangeSpringTool() { // TODO Auto-generated constructor stub } public physicsChangeSpringTool(Space cNet, PhysicsNet pN, HashMap<Edge, Edge> edges) { this.cNet = cNet; this.pN = pN; this.edges = edges; } @Override protected void dragged(MouseEvent event) { // TODO Auto-generated method stub } @Override protected void moved(MouseEvent event) { findTarget(event); if (target instanceof Geometric) { if (target instanceof Surface) { editor.getView().makeTarget(target); } if (target instanceof Edge) { editor.getView().makeTarget(target); } } } @Override protected void pressed(MouseEvent event) { findTarget(event); if (target instanceof Geometric) { if (target instanceof Surface) { editor.getView().makeTarget(target); Surface bS = (Surface) target; Collection<Edge> bEdges = bS.getEdges(); for (Edge bE : bEdges) { pN.scaleRestLengthFactor(bE, 1.1); } } if (target instanceof Edge) { editor.getView().makeTarget(target); Edge bE = (Edge) target; pN.scaleRestLengthFactor(bE, 1.1); } } } @Override protected void released(MouseEvent event) { // TODO Auto-generated method stub } } public static class physicsChangeWeightTool extends AbstractTool { PhysicsNet pN; //Physics Net = Simulation Object public physicsChangeWeightTool() { // TODO Auto-generated constructor stub } public physicsChangeWeightTool(PhysicsNet pN) { this.pN = pN; } @Override protected void dragged(MouseEvent event) { // TODO Auto-generated method stub } @Override protected void moved(MouseEvent event) { findTarget(event); if (target instanceof Geometric) { if (target instanceof Vertex) { editor.getView().makeTarget(target); } } } @Override protected void pressed(MouseEvent event) { findTarget(event); if (target instanceof Geometric) { if (target instanceof Vertex) { editor.getView().makeTarget(target); Vertex bV = (Vertex) target; pN.scaleParticleMass(bV,1.2); } } } @Override protected void released(MouseEvent event) { // TODO Auto-generated method stub } } } --- NEW FILE: PhysicsNet.java --- package net.sourceforge.bprocessor.packages.physics; import java.util.*; import net.sourceforge.bprocessor.model.Edge; import net.sourceforge.bprocessor.model.ParameterBlock; import net.sourceforge.bprocessor.model.Space; import net.sourceforge.bprocessor.model.Vertex; import net.sourceforge.bprocessor.model.Surface; public class PhysicsNet { //properties Space cNet; double gravity = -9.81; double globalParticleMass = 1.0; double spring_c = 4.4; //spring constant double spring_d = 0.5; //spring damping double particle_d = 3; //particle damping coefficient of drag boolean solid = false; HashMap<Vertex,PhysicsParticle> particles = new HashMap(); HashMap<Edge,PhysicsSpring> springs = new HashMap(); HashMap<Surface, PhysicsSurface> surfaces = new HashMap(); //constructor PhysicsNet(Space cNet, double gravity, double spring_constant, double spring_damping, double particle_damping, double mass, double restLengthFactor) { Map pMap = new HashMap(); globalParticleMass = mass; //this.bNet = (Space) bNet.copy(pMap); this.cNet = cNet; this.spring_c = spring_constant; this.spring_d = spring_damping; this.particle_d = particle_damping; this.solid = isSolid(); //create Particles and Springs from Vertices of b-Net Collection<Vertex> bVertices = cNet.getVertices(); Map<Vertex, List<Edge>> edgeMap = cNet.getEdgeMap(bVertices); int counter = 0; for (Vertex bV : bVertices) { particles.put(bV, new PhysicsParticle(bV, new Vertex(0,0,0), new Vertex(0,0,0), mass, counter)); counter++; } //create Springs Collection<Edge> bEdges = cNet.getEdges(); for (Edge bE : bEdges) { PhysicsParticle pA = particles.get(bE.getFrom()); PhysicsParticle pB = particles.get(bE.getTo()); PhysicsSpring pS = new PhysicsSpring(pA,pB,pA.pos.distance(pB.pos),spring_c); pS.restLengthFactor = restLengthFactor; springs.put(bE, pS); pA.connectSpring(pS); pB.connectSpring(pS); counter++;; saveSpringParameter(bE,pS); } //create PhysicsSurfaces Collection<Surface> bSurfaces = cNet.getSurfaces(); for (Surface bS : bSurfaces) { //create HashMaps for Surface //edges - springs //vertices - Particles List<Vertex> bSV = bS.getVertices(); HashMap<Vertex, PhysicsParticle> bSVP= new HashMap(); for (Vertex v : bSV) { PhysicsParticle p = (PhysicsParticle) particles.get(v); bSVP.put(v,p); } List<Edge> bSE = bS.getEdges(); HashMap<Edge, PhysicsSpring> bSES = new HashMap(); for (Edge e : bSE) { PhysicsSpring s = (PhysicsSpring) springs.get(e); bSES.put(e,s); } PhysicsSurface pS = new PhysicsSurface(bS,bSVP,bSES); surfaces.put(bS, pS); } } void saveSpringParameter(Edge e, PhysicsSpring pS) { ParameterBlock block = e.getParameters(); if (block == null) { block = new ParameterBlock(); e.setParameters(block); block.putDouble("Spring current Length", e.getLength()); block.putDouble("Spring Restlength", pS.eql); block.putDouble("Spring Constant", pS.c); } block.changeDouble("Spring current Length", e.getLength()); block.changeDouble("Spring Restlength", pS.eql); block.changeDouble("Spring Constant", pS.c); } void saveParticleParameter(Vertex v, PhysicsParticle pP) { ParameterBlock block = v.getParameters(); if (block == null) { block = new ParameterBlock(); v.setParameters(block); block.putDouble("Particle Weight [kg]", pP.m); } block.changeDouble("Particle Weight [kg]", pP.m); } double saveVolume (Space cNet) { double volume = 0.0; if (solid) { volume = calcVolume(); ParameterBlock block = cNet.getParameters(); if (block == null) { block = new ParameterBlock(); cNet.setParameters(block); block.putDouble("Volume", volume); } block.changeDouble("Volume", volume); } return volume; } void saveArea (Surface s) { ParameterBlock block = s.getParameters(); PhysicsSurface pS = surfaces.get(s); if (block == null) { block = new ParameterBlock(); s.setParameters(block); block.putDouble("Area", pS.calcArea()); } block.changeDouble("Area", pS.calcArea()); } void updatePos(Vertex cV) { PhysicsParticle pA = particles.get(cV); pA.pos = new Vertex(cV.getX(),cV.getY(), cV.getZ()); pA.nPos = new Vertex(cV.getX(),cV.getY(), cV.getZ()); pA.lastPos = new Vertex(cV.getX(),cV.getY(), cV.getZ()); } void updateMass(double mass) { Iterator it = particles.entrySet().iterator(); while (it.hasNext()) { Map.Entry ee = (Map.Entry)it.next(); PhysicsParticle p = (PhysicsParticle)ee.getValue(); //only change value if mass of particle wasn't changed locally. if (p.m == globalParticleMass) { p.m = mass; } } //set globalParticleMass to current value. globalParticleMass = mass; } void scaleParticleMass(Vertex v, double scale) { PhysicsParticle p = (PhysicsParticle)particles.get(v); p.m = p.m * scale; } void updateRestLength(Edge e, double eql) { PhysicsSpring s = (PhysicsSpring)springs.get(e); s.eql = eql; } void setRestLengthFactor (Edge e, double restLengthFactor) { PhysicsSpring s = (PhysicsSpring)springs.get(e); s.restLengthFactor = restLengthFactor; } void scaleRestLengthFactor (Edge e, double scale) { PhysicsSpring s = (PhysicsSpring)springs.get(e); s.restLengthScale = s.restLengthScale * scale; } void updateSpringConstant(double springConstant) { Iterator it = springs.entrySet().iterator(); while (it.hasNext()) { Map.Entry ee = (Map.Entry)it.next(); PhysicsSpring s = (PhysicsSpring)ee.getValue(); s.c = springConstant; } } void update(Space guides, double time, double equalConstant, double equalDamping, double rectConstant, double rectDamping, double planeConstant, double planeDamping, double volume) { Iterator it; //calculate surface forces double currentVolume = saveVolume(cNet); it = surfaces.entrySet().iterator(); while (it.hasNext()) { Map.Entry ee = (Map.Entry)it.next(); PhysicsSurface s = (PhysicsSurface)ee.getValue(); s.equalizeEdges(time, equalConstant, equalDamping); s.quadToRect(guides, time, rectConstant, rectDamping); s.planarize(guides, time, planeConstant, planeDamping); if ((volume>0) && (solid)) { double normalForce = s.calcArea()*volume/currentVolume; s.normalForce(guides, time, normalForce); } saveArea((Surface) ee.getKey()); } //claculate particle movement it = particles.entrySet().iterator(); while (it.hasNext()) { Map.Entry ee = (Map.Entry)it.next(); PhysicsParticle p = (PhysicsParticle)ee.getValue(); p.move(time, gravity, particle_d); } //move nodes of b-net to particle positions it = particles.entrySet().iterator(); while (it.hasNext()) { Map.Entry ee = (Map.Entry)it.next(); Vertex v = (Vertex)ee.getKey(); PhysicsParticle p = (PhysicsParticle)ee.getValue(); v.set(p.nPos); saveParticleParameter(v,p); } //update springs it = springs.entrySet().iterator(); while (it.hasNext()) { Map.Entry ee = (Map.Entry)it.next(); Edge e = (Edge)ee.getKey(); PhysicsSpring s = (PhysicsSpring)ee.getValue(); s.update(time, spring_d); saveSpringParameter(e,s); } cNet.update(); } //check if c-Net forms a solid. //each edge is connected to 2 surfaces. boolean isSolid() { boolean solid = true; Collection<Edge> cEdges = cNet.getEdges(); for (Edge nE : cEdges) { Set<Surface> cSurfaces = nE.getSurfaces(); if (cSurfaces.size()<2) solid = false; } return solid; } //calculate volume of solid double calcVolume() { double v = 0.0; Iterator it = surfaces.entrySet().iterator(); while (it.hasNext()) { Map.Entry ee = (Map.Entry)it.next(); Surface s = (Surface)ee.getKey(); PhysicsSurface pS = (PhysicsSurface)ee.getValue(); List<Vertex> vertices = s.getVertices(); Vertex p = vertices.get(0); Vertex n = pS.averageNormal(); //n.normalize(); double test = p.dot(n); v = v + pS.calcArea()* test; } v = Math.abs(v)/3; return v; } } --- NEW FILE: PhysicsPlane.java --- package net.sourceforge.bprocessor.packages.physics; import net.sourceforge.bprocessor.model.Vertex; public class PhysicsPlane { //properties of a plane //3 points Vertex[] pPoints = new Vertex[3]; //normal Vertex nVec = new Vertex(0,0,0); //origin Vertex origin; //directions Vertex dirX; Vertex dirY; //distance double d = 0; //constructor from 3 points PhysicsPlane (Vertex origin, Vertex point1, Vertex point2) { //save plane points this.origin = new Vertex(origin.getX(),origin.getY(), origin.getZ()); dirX = new Vertex(point1.getX(),point1.getY(), point1.getZ()); dirY = new Vertex(point2.getX(),point2.getY(), point2.getZ()); pPoints[0] = this.origin; pPoints[1] = new Vertex(point1.getX(),point1.getY(), point1.getZ()); pPoints[2] = new Vertex(point2.getX(),point2.getY(), point2.getZ()); //get plane directions dirX = dirX.minus(origin); dirY = dirY.minus(origin); //calculate normal nVec = dirX.cross(dirY); nVec.normalize(); d = nVec.dot(origin); } //constructor from normal and origin PhysicsPlane (Vertex nVec, Vertex origin) { this.nVec = nVec.copy(); this.nVec.normalize(); d = nVec.dot(origin); } //Normal Vector from point onto Plane Vertex PointNormalToPlane(Vertex pnt) { double t0; Vertex x0; Vertex lNorm; Vertex PtoE; t0 = (d-nVec.dot(pnt)) / (nVec.dot(nVec)); lNorm = new Vertex(nVec.getX(), nVec.getY(),nVec.getZ()); lNorm = lNorm.scale(t0); x0 = new Vertex (pnt.getX(), pnt.getY(), pnt.getZ()); x0 = x0.add(lNorm); PtoE = x0; PtoE = PtoE.minus(pnt); return PtoE; } Vertex PointProjectToPlane(Vertex pnt) { double t0; Vertex x0; Vertex lNorm; Vertex PtoE; t0 = (d-nVec.dot(pnt)) / (nVec.dot(nVec)); lNorm = new Vertex(nVec.getX(), nVec.getY(),nVec.getZ()); lNorm = lNorm.scale(t0); x0 = new Vertex (pnt.getX(), pnt.getY(), pnt.getZ()); x0 = x0.add(lNorm); PtoE = x0; return PtoE; } } |