[Bprocessor-commit] model/src/net/sourceforge/bprocessor/model/plugin PhysicsParticle.java, NONE,
Status: Pre-Alpha
Brought to you by:
henryml
From: Sebastian G. <sg...@us...> - 2011-04-26 06:23:05
|
Update of /cvsroot/bprocessor/model/src/net/sourceforge/bprocessor/model/plugin In directory vz-cvs-2.sog:/tmp/cvs-serv30195/src/net/sourceforge/bprocessor/model/plugin Modified Files: NetCommand.java Added Files: PhysicsParticle.java PhysicsNet.java PhysicsPlane.java PhysicsSpring.java PhysicsSurface.java PhysicsPackage.java Removed Files: HangingChainPackage.java Log Message: Physics System --- NEW FILE: PhysicsSpring.java --- package net.sourceforge.bprocessor.model.plugin; 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 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; } //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)*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.model.plugin; 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, boolean fixed, int ID) { pos = node; vel = velocity; a = acceleration; m = mass; fix = fixed; 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 != 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.model.plugin; import java.util.ArrayList; import java.util.HashMap; 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(100)); } } 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() { 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; } 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); } } } } --- HangingChainPackage.java DELETED --- Index: NetCommand.java =================================================================== RCS file: /cvsroot/bprocessor/model/src/net/sourceforge/bprocessor/model/plugin/NetCommand.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** NetCommand.java 13 Apr 2011 08:14:53 -0000 1.3 --- NetCommand.java 26 Apr 2011 06:23:02 -0000 1.4 *************** *** 58,61 **** --- 58,68 ---- } } + public void vertex(Vertex a) { + if (vertices != null) { + vertices.add(a); + } else { + owner.add(a); + } + } public void endSurface() { if (vertices != null) { *************** *** 80,83 **** --- 87,97 ---- } + public void line(Vertex from, Vertex to) { + beginSurface(); + vertex(from); + vertex(to); + endSurface(); + } + public void circle(double radius) { int n = 36; *************** *** 97,101 **** owner.add(hanging); this.net = net; ! } } --- 111,121 ---- owner.add(hanging); this.net = net; ! } ! ! public void initializeNoItem(Space net) { ! owner = net.getOwner(); ! //Space hanging = Item.createNet("Hanging Chains"); ! //owner.add(hanging); ! this.net = net; } } --- NEW FILE: PhysicsPackage.java --- package net.sourceforge.bprocessor.model.plugin; import net.sourceforge.bprocessor.model.Command; import net.sourceforge.bprocessor.model.Edge; import net.sourceforge.bprocessor.model.Item; import net.sourceforge.bprocessor.model.Space; import net.sourceforge.bprocessor.model.Vertex; import net.sourceforge.bprocessor.model.plugin.PhysicsNet; import java.util.*; /* * To Do * 1. Modify new net while simulation is running, i.e. corner property, etc. * 2. Change to original net -> changes new net * 3. Parameters, toggles and sliders * 4. Planarity and regularity of panels * 5. Add parameters to b-net and save them! * 6. Subdivision */ public class PhysicsPackage { public static class Springsystem extends NetCommand { Space union; PhysicsNet pN; //physical Net Space cNet; //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; 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 = 1.1; parameters.put("Spring Restlength Factor",restLengthFactor); springConstant = 2.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 Spring Damping [N sec/m]", equalDamping); rectConstant = 0.0; parameters.put("Rectangular Quads Spring Constant rc [N/m]",rectConstant); rectDamping = 2.0; parameters.put("Rectangular Quads Spring Damping [N sec/m]", rectDamping); planeConstant = 0.0; parameters.put("Planarity Spring Constant pc [N/m]",planeConstant); planeDamping = 2.0; parameters.put("Planarity Spring Damping [N sec/m]", planeDamping); normalForce = 0.0; parameters.put("Normal Surface Force [N]", normalForce); super.initializeNoItem(net); //create copy of b-Net Map map = new HashMap(); //map = net.getOwnParameters(); cNet = net.copy(map); //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()); } } } //create physics Net pN = new PhysicsNet(cNet, gravity, springConstant, cDamp, pDamp, mass, restLengthFactor); } 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 Double oldRLF = restLengthFactor; restLengthFactor = (Double) parameters.getDouble("Spring Restlength Factor"); if (oldRLF!=restLengthFactor) { pN.updateRestLength(restLengthFactor); } //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 Spring Damping [N sec/m]"); //rectangular quads parameters rectConstant = (Double) parameters.get("Rectangular Quads Spring Constant rc [N/m]"); rectDamping = (Double) parameters.get("Rectangular Quads Spring Damping [N sec/m]"); //Planarity planeConstant = (Double) parameters.get("Planarity Spring Constant pc [N/m]"); planeDamping = (Double) parameters.get("Planarity Spring Damping [N sec/m]"); //normal Force normalForce = (Double) parameters.get("Normal Surface Force [N]"); //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 cNet.edit(); pN.update(guides, 0.02, equalConstant, equalDamping, rectConstant, rectDamping, planeConstant, planeDamping, normalForce); union.add(cNet); } } public PhysicsPackage() { Command.register(Springsystem.class); } } --- NEW FILE: PhysicsNet.java --- package net.sourceforge.bprocessor.model.plugin; import java.util.*; 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 PhysicsNet { //properties Space bNet; double gravity = -9.81; double spring_c = 4.4; //spring constant double spring_d = 0.5; //spring damping double particle_d = 3; //particle damping coefficient of drag HashMap<Vertex,PhysicsParticle> particles = new HashMap(); HashMap<Edge,PhysicsSpring> springs = new HashMap(); HashMap<Surface, PhysicsSurface> surfaces = new HashMap(); PhysicsNet(Space bNet, double gravity, double spring_constant, double spring_damping, double particle_damping, double mass, double restLengthFactor) { Map pMap = new HashMap(); this.bNet = (Space) bNet.copy(pMap); this.spring_c = spring_constant; this.spring_d = spring_damping; this.particle_d = particle_damping; //create Particles and Springs from Vertices of b-Net Collection<Vertex> bVertices = bNet.getVertices(); Map<Vertex, List<Edge>> edgeMap = bNet.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, bV.isCorner(),counter)); counter++; } //create Springs Collection<Edge> bEdges = bNet.getEdges(); for (Edge bE : bEdges) { PhysicsParticle pA = particles.get(bE.getFrom()); PhysicsParticle pB = particles.get(bE.getTo()); PhysicsSpring pS = new PhysicsSpring(pA,pB,restLengthFactor*pA.pos.distance(pB.pos),spring_c); springs.put(bE, pS); pA.connectSpring(pS); pB.connectSpring(pS); counter++;; } //create PhysicsSurfaces Collection<Surface> bSurfaces = bNet.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 updateMass(double mass) { Iterator it = particles.entrySet().iterator(); while (it.hasNext()) { Map.Entry ee = (Map.Entry)it.next(); PhysicsParticle p = (PhysicsParticle)ee.getValue(); p.m = mass; } } void updateRestLength(double restLengthFactor) { Iterator it = springs.entrySet().iterator(); while (it.hasNext()) { Map.Entry ee = (Map.Entry)it.next(); PhysicsSpring s = (PhysicsSpring)ee.getValue(); s.eql = s.startL * restLengthFactor; } } 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 normalForce) { Iterator it; //calculate surface forces 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); s.normalForce(guides, time, normalForce); } //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); } //update springs it = springs.entrySet().iterator(); while (it.hasNext()) { Map.Entry ee = (Map.Entry)it.next(); PhysicsSpring s = (PhysicsSpring)ee.getValue(); s.update(time, spring_d); } bNet.update(); } } --- NEW FILE: PhysicsPlane.java --- package net.sourceforge.bprocessor.model.plugin; 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; } } |