From 5031df4b26afd515274b5ca34f0d5380a99e4223 Mon Sep 17 00:00:00 2001 From: Jakob Odersky Date: Sat, 28 Nov 2009 20:25:35 +0000 Subject: Minor graphyx modifications. Added tests. Added 'PrismaticJoint' (still incomplete). Started to transfer 'ForceJoints' to ordinary joints who use only constraints for correction. Started to add materials. --- doc/graphyx/graphics/Parser$object.html | 20 +++--- doc/sims/dynamics/World.html | 36 +++++----- doc/sims/dynamics/joints/SpringJoint.html | 8 +-- doc/sims/math/Matrix22.html | 12 ++-- doc/sims/prefabs/Ragdoll.html | 4 +- doc/sims/util/RelativeVector.html | 8 +-- src/graphyx/Graphyx.scala | 3 + src/graphyx/graphics/GraphicalShape.scala | 4 +- src/graphyx/graphics/Parser.scala | 3 +- src/graphyx/gui/AboutHelpFrame.scala | 2 +- src/graphyx/gui/OptionsPanel.scala | 10 ++- src/graphyx/gui/WorldPanel.scala | 30 +++++++- src/graphyx/tests/Atom.scala | 35 +++++++++ src/graphyx/tests/Spring.scala | 32 +++++++++ src/graphyx/tests/Wave.scala | 27 +++++++ src/sims/collision/PolyCollision.scala | 6 +- src/sims/dynamics/World.scala | 2 +- src/sims/dynamics/joints/SpringJoint.scala | 32 +++++++-- src/sims/dynamics/joints/test/PrismaticJoint.scala | 84 ++++++++++++++++++++++ src/sims/materials/Material.scala | 7 ++ src/sims/materials/Rubber.scala | 5 ++ src/sims/materials/Steel.scala | 5 ++ src/sims/prefabs/Ragdoll.scala | 2 +- 23 files changed, 319 insertions(+), 58 deletions(-) create mode 100644 src/graphyx/tests/Atom.scala create mode 100644 src/graphyx/tests/Spring.scala create mode 100644 src/graphyx/tests/Wave.scala create mode 100644 src/sims/dynamics/joints/test/PrismaticJoint.scala create mode 100644 src/sims/materials/Material.scala create mode 100644 src/sims/materials/Rubber.scala create mode 100644 src/sims/materials/Steel.scala diff --git a/doc/graphyx/graphics/Parser$object.html b/doc/graphyx/graphics/Parser$object.html index 4e88dfa..a03729d 100644 --- a/doc/graphyx/graphics/Parser$object.html +++ b/doc/graphyx/graphics/Parser$object.html @@ -56,8 +56,8 @@ def - toGraphical - (real : Body) : GraphicalBody + toGraphical + (real : AABB) : GraphicalAABB @@ -67,8 +67,8 @@ def - toGraphical - (real : Pair) : GraphicalPair + toGraphical + (real : Shape) : GraphicalShape with scala.Product @@ -78,8 +78,8 @@ def - toGraphical - (real : Shape) : GraphicalShape with scala.Product + toGraphical + (real : Pair) : GraphicalPair @@ -100,8 +100,8 @@ def - toGraphical - (real : AABB) : GraphicalAABB + toGraphical + (real : Collision) : GraphicalCollision @@ -111,8 +111,8 @@ def - toGraphical - (real : Collision) : GraphicalCollision + toGraphical + (real : Body) : GraphicalBody diff --git a/doc/sims/dynamics/World.html b/doc/sims/dynamics/World.html index 6c882fe..f9b0217 100644 --- a/doc/sims/dynamics/World.html +++ b/doc/sims/dynamics/World.html @@ -202,10 +202,10 @@ def - += - (body : Body) : Unit + += + (p : Prefab) : Unit -
Fuegt dieser Welt einen Koerper hinzu.
+
Fuegt dieser Welt ein vorangefertigtes System vaus Koerpern und Verbindungen hinzu.
@@ -213,10 +213,10 @@ def - += - (p : Prefab) : Unit + += + (joint : Joint) : Unit -
Fuegt dieser Welt ein vorangefertigtes System vaus Koerpern und Verbindungen hinzu.
+
Fuegt dieser Welt eine Verbindung hinzu.
@@ -224,10 +224,10 @@ def - += - (joint : Joint) : Unit + += + (body : Body) : Unit -
Fuegt dieser Welt eine Verbindung hinzu.
+
Fuegt dieser Welt einen Koerper hinzu.
@@ -246,10 +246,10 @@ def - -= - (body : Body) : Unit + -= + (p : Prefab) : Unit -
Entfernt den gegebenen Koerper aus dieser Welt.
+
Entfernt das gegebene System aus Koerpern und Verbindungen aus dieser Welt.
@@ -257,10 +257,10 @@ def - -= - (joint : Joint) : Unit + -= + (body : Body) : Unit -
Entfernt die gegebene Verbindung aus dieser Welt.
+
Entfernt den gegebenen Koerper aus dieser Welt.
@@ -268,10 +268,10 @@ def - -= - (p : Prefab) : Unit + -= + (joint : Joint) : Unit -
Entfernt das gegebene System aus Koerpern und Verbindungen aus dieser Welt.
+
Entfernt die gegebene Verbindung aus dieser Welt.
diff --git a/doc/sims/dynamics/joints/SpringJoint.html b/doc/sims/dynamics/joints/SpringJoint.html index ba601bb..b361835 100644 --- a/doc/sims/dynamics/joints/SpringJoint.html +++ b/doc/sims/dynamics/joints/SpringJoint.html @@ -55,8 +55,8 @@ def - this - (node1 : Body, node2 : Body, springConstant : Double, initialLength : Double) : SpringJoint + this + (node1 : Body, anchor1 : Vector2D, node2 : Body, anchor2 : Vector2D, springConstant : Double) : SpringJoint @@ -66,8 +66,8 @@ def - this - (node1 : Body, anchor1 : Vector2D, node2 : Body, anchor2 : Vector2D, springConstant : Double) : SpringJoint + this + (node1 : Body, node2 : Body, springConstant : Double, initialLength : Double) : SpringJoint diff --git a/doc/sims/math/Matrix22.html b/doc/sims/math/Matrix22.html index fe05b63..b3a5906 100644 --- a/doc/sims/math/Matrix22.html +++ b/doc/sims/math/Matrix22.html @@ -72,10 +72,10 @@ def - * - (m : Matrix22) : Matrix22 + * + (v : Vector2D) : Vector2D -
Multiplikation mit einer anderen 2x2-Matrix.
+
Multiplikation mit einer 2x1-Matrix (2-dimensionaler Vektor).
@@ -83,10 +83,10 @@ def - * - (v : Vector2D) : Vector2D + * + (m : Matrix22) : Matrix22 -
Multiplikation mit einer 2x1-Matrix (2-dimensionaler Vektor).
+
Multiplikation mit einer anderen 2x2-Matrix.
diff --git a/doc/sims/prefabs/Ragdoll.html b/doc/sims/prefabs/Ragdoll.html index f7cc846..0ae14d2 100644 --- a/doc/sims/prefabs/Ragdoll.html +++ b/doc/sims/prefabs/Ragdoll.html @@ -131,7 +131,7 @@ joints - : scala.List[RevoluteJoint] + : scala.Nil @@ -402,7 +402,7 @@ override val - joints : scala.List[RevoluteJoint] + joints : scala.Nil
diff --git a/doc/sims/util/RelativeVector.html b/doc/sims/util/RelativeVector.html index ed726df..323edb5 100644 --- a/doc/sims/util/RelativeVector.html +++ b/doc/sims/util/RelativeVector.html @@ -87,8 +87,8 @@ def - from - (s : Shape) : Vector2D + from + (point : Vector2D) : Vector2D @@ -98,8 +98,8 @@ def - from - (point : Vector2D) : Vector2D + from + (s : Shape) : Vector2D diff --git a/src/graphyx/Graphyx.scala b/src/graphyx/Graphyx.scala index 81a8ee8..01caea8 100644 --- a/src/graphyx/Graphyx.scala +++ b/src/graphyx/Graphyx.scala @@ -18,7 +18,10 @@ object Graphyx{ CompositeShape, Joints1, Joints2, + Spring, + Atom, Chain, + Wave, Stacking, BallStack, Cup, diff --git a/src/graphyx/graphics/GraphicalShape.scala b/src/graphyx/graphics/GraphicalShape.scala index e6f61a7..256c041 100644 --- a/src/graphyx/graphics/GraphicalShape.scala +++ b/src/graphyx/graphics/GraphicalShape.scala @@ -7,8 +7,8 @@ package graphyx.graphics import sims.dynamics._ -trait GraphicalShape extends Shape with GraphicalObject{ - val real: Shape +trait GraphicalShape extends Shape with GraphicalObject{ + val real: Shape override val uid: Int = real.uid pos = real.pos rotation = real.rotation diff --git a/src/graphyx/graphics/Parser.scala b/src/graphyx/graphics/Parser.scala index 7871ae8..9468d16 100644 --- a/src/graphyx/graphics/Parser.scala +++ b/src/graphyx/graphics/Parser.scala @@ -24,7 +24,8 @@ object Parser { case j: DistanceJoint => GraphicalDistanceJoint(j) case j: SpringJoint => GraphicalSpringJoint(j) case j: RevoluteJoint => GraphicalRevoluteJoint(j) - case _ => throw new IllegalArgumentException("Cannot cast '" + real.getClass + "' to a graphical object.") + case j: Joint => if (!throwOnUnknown) new GraphicalJoint{override val real = j; def draw = ()} + else throw new IllegalArgumentException("Cannot cast '" + real.getClass + "' to a graphical object.") } def toGraphical(real: Collision) = GraphicalCollision(real) diff --git a/src/graphyx/gui/AboutHelpFrame.scala b/src/graphyx/gui/AboutHelpFrame.scala index 5afa58e..4dba9f1 100644 --- a/src/graphyx/gui/AboutHelpFrame.scala +++ b/src/graphyx/gui/AboutHelpFrame.scala @@ -14,7 +14,7 @@ class AboutHelpFrame extends Frame { |SiMS and Graphyx are made available under the MIT License | |http://sourceforge.net/projects/simplemechanics/""".stripMargin - ) + ) {editable = false} } object AboutHelpFrame { diff --git a/src/graphyx/gui/OptionsPanel.scala b/src/graphyx/gui/OptionsPanel.scala index 3ec3921..525f352 100644 --- a/src/graphyx/gui/OptionsPanel.scala +++ b/src/graphyx/gui/OptionsPanel.scala @@ -13,7 +13,7 @@ import scala.swing._ import scala.swing.event._ import GridBagPanel._ -class OptionsPanel(container: Container) extends GridPanel(11,2){ +class OptionsPanel(container: Container) extends GridPanel(12,2){ /* val c = new Constraints c.anchor = Anchor.West @@ -55,6 +55,9 @@ class OptionsPanel(container: Container) extends GridPanel(11,2){ val lblDrawCollisions = new Label("Collisions") val chckDrawCollisions = new CheckBox {selected = false} + val lblTrace = new Label("Trace") + val chckTrace = new CheckBox {selected = false} + val components = List( lblTimeStep, txtTimeStep, lblIterations, txtIterations, @@ -66,7 +69,8 @@ class OptionsPanel(container: Container) extends GridPanel(11,2){ lblDrawJoints, chckDrawJoints, lblDrawAABBs, chckDrawAABBs, lblDrawPairs, chckDrawPairs, - lblDrawCollisions, chckDrawCollisions + lblDrawCollisions, chckDrawCollisions, + lblTrace, chckTrace ) contents ++= components listenTo(components: _*) @@ -82,6 +86,7 @@ class OptionsPanel(container: Container) extends GridPanel(11,2){ case ButtonClicked(`chckDrawAABBs`) => container.mainFrame.mainPanel.worldPanel.drawAABBs = chckDrawAABBs.selected case ButtonClicked(`chckDrawPairs`) => container.mainFrame.mainPanel.worldPanel.drawPairs = chckDrawPairs.selected case ButtonClicked(`chckDrawCollisions`) => container.mainFrame.mainPanel.worldPanel.drawCollisions = chckDrawCollisions.selected + case ButtonClicked(`chckTrace`) => container.mainFrame.mainPanel.worldPanel.trace = chckTrace.selected } def update() = { @@ -97,6 +102,7 @@ class OptionsPanel(container: Container) extends GridPanel(11,2){ chckDrawAABBs.selected = container.mainFrame.mainPanel.worldPanel.drawAABBs chckDrawPairs.selected = container.mainFrame.mainPanel.worldPanel.drawPairs chckDrawCollisions.selected = container.mainFrame.mainPanel.worldPanel.drawCollisions + chckTrace.selected = container.mainFrame.mainPanel.worldPanel.trace } diff --git a/src/graphyx/gui/WorldPanel.scala b/src/graphyx/gui/WorldPanel.scala index 13765e5..cd91f00 100644 --- a/src/graphyx/gui/WorldPanel.scala +++ b/src/graphyx/gui/WorldPanel.scala @@ -42,6 +42,7 @@ class WorldPanel(container: Container) extends BoxPanel(Orientation.Vertical){ var drawAABBs = false var drawPairs = false var drawCollisions = false + var trace = false override def paintComponent(g: java.awt.Graphics) = { var parts: Seq[graphyx.graphics.Drawable] = Seq() @@ -55,6 +56,7 @@ class WorldPanel(container: Container) extends BoxPanel(Orientation.Vertical){ drawAxes(g) g.translate(offset.x.toInt, -offset.y.toInt) drawParts(parts, g) + if (trace) trace(scene.shapes, g) g.translate(-offset.x.toInt, offset.y.toInt) } @@ -80,6 +82,30 @@ class WorldPanel(container: Container) extends BoxPanel(Orientation.Vertical){ } } + import collection.mutable._ + val prevPos: collection.mutable.Map[Int, collection.mutable.Queue[Vector2D]] = Map() + def trace(shapes: Iterable[graphics.GraphicalShape], g: java.awt.Graphics) = { + for (s <- shapes) { + s.g = g + s.windowHeight = super.size.height + s.ppm = ppm + s.scale = this.scale + + + if (!prevPos.contains(s.uid)) prevPos += (s.uid -> new Queue[Vector2D]) + else { + prevPos(s.uid).enqueue(s.pos) + for(i <- 0 until prevPos(s.uid).length - 1) { + val sp = prevPos(s.uid)(i) + val ep = prevPos(s.uid)(i + 1) + s.g.setColor(java.awt.Color.cyan) + s.drawLine(sp, ep) + } + if (prevPos(s.uid).length == 50) prevPos(s.uid).dequeue + } + } + } + def getBody(p: Vector2D): Option[Body] = { val shape = scene.shapes.find(_.contains(p)) if (shape != None) Some(shape.get.real.body) @@ -106,8 +132,10 @@ class WorldPanel(container: Container) extends BoxPanel(Orientation.Vertical){ case MousePressed(c,p,x,y,b) => { mousePressed = true; startPoint = p; endPoint = p x match { - case 1024 if (getBody(p) != None) => grab(getBody(p).get, p) + case 1024 if (getBody(p) != None) => grab(getBody(p).get, p) + case 1152 if (getBody(p) != None) => {grabbedBody = Some(new GrabbedBody(getBody(p).get, p)); popup.body = grabbedBody.get.body; popup.peer.setLocation(p); popup.visible = true} case 4096 if (getBody(p) != None) => {grabbedBody = Some(new GrabbedBody(getBody(p).get, p)); popup.body = grabbedBody.get.body; popup.peer.setLocation(p); popup.visible = true} + case _ => () } } diff --git a/src/graphyx/tests/Atom.scala b/src/graphyx/tests/Atom.scala new file mode 100644 index 0000000..84fe05c --- /dev/null +++ b/src/graphyx/tests/Atom.scala @@ -0,0 +1,35 @@ +package graphyx.tests + +import sims.dynamics._ +import sims.dynamics.joints._ +import sims.geometry._ + +object Atom extends Test{ + val title = "Atom" + val world = new World + + var nucleus = new Body(Circle(0.05, 1000)) {fixed = true} + var electrons: List[Body] = Nil + var connections: List[SpringJoint] = Nil + + def init = { + world -= nucleus + nucleus = new Body(Circle(0.05, 10)) {fixed = true} + world += nucleus + world --= electrons + electrons = Nil + for (c <- connections) world -= c + connections = Nil + } + + override def fireEvent = { + val e = (new Circle(0.1, 10) {pos = Vector2D(0, -1)}).asBody + e.linearVelocity = Vector2D(-50,100) + electrons = e :: electrons + world += e + + val c = new SpringJoint(nucleus, e, 500) + connections = c :: connections + world += c + } +} diff --git a/src/graphyx/tests/Spring.scala b/src/graphyx/tests/Spring.scala new file mode 100644 index 0000000..4eec8de --- /dev/null +++ b/src/graphyx/tests/Spring.scala @@ -0,0 +1,32 @@ +package graphyx.tests + +import sims.dynamics._ +import sims.dynamics.joints._ +import sims.geometry._ +import java.io._ + +object Spring extends Test{ + val title = "Spring" + val fout = new java.io.FileOutputStream("out.csv") + val sout = new java.io.PrintStream(fout) + val world = new World { + override def postStep = { + //for (b <- bodies; if (b.monitor)) sout.println(monitors(0)._2(b)) + } + } + + def init = { + val anchor = Circle(0.05, 10).asBody + anchor.fixed = true + val particle = (new Circle(0.1, 10) {pos = Vector2D(0, -1)}).asBody + val spring = new SpringJoint(anchor, particle, 500, 0.6) + //val spring = new PrismaticJoint(anchor, particle) + spring.damping = 1 + particle.monitor = true + world.monitors += ("", _.pos.y.toString) + + world += anchor + world += particle + world += spring + } +} diff --git a/src/graphyx/tests/Wave.scala b/src/graphyx/tests/Wave.scala new file mode 100644 index 0000000..62ec194 --- /dev/null +++ b/src/graphyx/tests/Wave.scala @@ -0,0 +1,27 @@ +package graphyx.tests + +import sims.dynamics._ +import sims.dynamics.joints._ +import sims.dynamics.joints.test._ +import sims.geometry._ + +object Wave extends Test{ + val title = "Wave" + val world = new World {gravity = Vector2D.Null} + + def init = { + val n = 50 + val anchors = for (i <- (0 to n).toList) yield (new Body(new Circle(0.01,1) {pos = Vector2D(0.4 * i, 5)}) {fixed = true}) + val particles = for (i <- (0 to n).toList) yield (new Body(new Circle(0.1,10) {pos = Vector2D(0.4 * i, 0)})) + val rails = (for (i <- (0 to n).toList) yield (new PrismaticJoint(anchors(i), particles(i)))) + val springs = (for (i <- (0 to n).toList) yield (new SpringJoint(anchors(i), particles(i), 5)))// {damping = 0.00})) + world ++= anchors + world ++= particles + for (j <- rails ++ springs) world += j + + val lateralSprings = (for (i <- (0 to (n - 1)).toList) yield (new SpringJoint(particles(i), particles(i + 1), 50.0))) + for (j <- lateralSprings) world += j + + } + +} diff --git a/src/sims/collision/PolyCollision.scala b/src/sims/collision/PolyCollision.scala index bbe5568..3eeb7ca 100644 --- a/src/sims/collision/PolyCollision.scala +++ b/src/sims/collision/PolyCollision.scala @@ -40,11 +40,15 @@ case class PolyCollision(p1: ConvexPolygon, p2: ConvexPolygon) extends Collision lazy val shape2 = incPoly.asInstanceOf[Shape] lazy val normal = refPoly.sides(minOverlap.sideNum).n0 - lazy val points = (for (v <- incPoly.vertices; if refPoly.contains(v)) yield v) ++ + lazy val points = (for (v <- incPoly.vertices; if refPoly.contains(v)) yield v)++ + (for (v <- refPoly.vertices; if incPoly.contains(v)) yield v) + + /* ++ (for (s <- incPoly.sides; val clip = s.clipToSegment(refPoly.sides((refPoly.sides.length - (minOverlap.sideNum + 1)) % refPoly.sides.length)); if (clip != None)) yield clip.get) ++ (for (s <- incPoly.sides; val clip = s.clipToSegment(refPoly.sides((refPoly.sides.length - (minOverlap.sideNum - 1)) % refPoly.sides.length)); if (clip != None)) yield clip.get) + */ } diff --git a/src/sims/dynamics/World.scala b/src/sims/dynamics/World.scala index d7ac8ae..7b165f5 100644 --- a/src/sims/dynamics/World.scala +++ b/src/sims/dynamics/World.scala @@ -67,7 +67,7 @@ class World { for (j <- p.joints) this += j } - def ++=(bs: Seq[Body]) = for(b <- bs) this += b + def ++=(bs: Seq[Body]): Unit = for(b <- bs) this += b /**Entfernt den gegebenen Koerper aus dieser Welt.*/ def -=(body: Body): Unit = bodies -= body diff --git a/src/sims/dynamics/joints/SpringJoint.scala b/src/sims/dynamics/joints/SpringJoint.scala index f03b35d..67ea57f 100644 --- a/src/sims/dynamics/joints/SpringJoint.scala +++ b/src/sims/dynamics/joints/SpringJoint.scala @@ -46,15 +46,39 @@ case class SpringJoint(node1: Body, anchor1: Vector2D, node2: Body, anchor2: Vec /**Relative Position der Bindungspunkte.*/ def x = connection2 - connection1 + /**Relative Geschwindigkeit der Bindungspunkte.*/ + def v = node2.velocityOfPoint(connection2) - node1.velocityOfPoint(connection1) + /**Ergibt die Federkraft nach dem Hookschen Gesetz.*/ def force = (x.length - initialLength) * springConstant /**Uebt die Federkraft auf die Bindungspunkte aus.*/ def applyForce() = { - node1.applyForce(x.unit * force - ((node1 velocityOfPoint connection1) * damping) project x, connection1) - node2.applyForce(-x.unit * force - ((node2 velocityOfPoint connection2) * damping) project x, connection2) + node1.applyForce(x.unit * force - (v * damping) project x, connection1) + node2.applyForce(-x.unit * force - (v * damping) project x, connection2) + //println("this should not happen") } - def correctPosition(h: Double) = () - def correctVelocity(h: Double) = () + def correctVelocity(h: Double) = { + /* + val x = this.x //relativer Abstand + val v = this.v //relative Geschwindigkeit + val r1 = (connection1 - node1.pos) //Abstand Punkt-Schwerpunkt, Koerper 1 + val r2 = (connection2 - node2.pos) //Abstand Punkt-Schwerpunkt, Koerper 2 + val cr1 = r1 cross x.unit //Kreuzprodukt + val cr2 = r2 cross x.unit //Kreuzprodukt + val Cdot = x.unit dot v //Velocity-Constraint + val invMass = 1/node1.mass + 1/node1.I * cr1 * cr1 + 1/node2.mass + 1/node2.I * cr2 * cr2 //=J M^-1 JT + val m = if (invMass == 0.0) 0.0 else 1/invMass //Test um Nulldivision zu vermeiden + val lambda = Math.min(Math.max(-this.force * h, (-m * Cdot)), this.force * h) + println (force * h, -m * Cdot) + val impulse = x.unit * lambda + node1.applyImpulse(-impulse, connection1) + node2.applyImpulse(impulse, connection2) + */ + } + + def correctPosition(h: Double) = { + + } } \ No newline at end of file diff --git a/src/sims/dynamics/joints/test/PrismaticJoint.scala b/src/sims/dynamics/joints/test/PrismaticJoint.scala new file mode 100644 index 0000000..f163261 --- /dev/null +++ b/src/sims/dynamics/joints/test/PrismaticJoint.scala @@ -0,0 +1,84 @@ +package sims.dynamics.joints.test + +import sims.geometry._ + +case class PrismaticJoint(node1: Body, anchor1: Vector2D, node2: Body, anchor2: Vector2D) extends Joint{ + def this(node1: Body, node2: Body) = this(node1, node1.pos, node2, node2.pos) + + val angle = node2.rotation - node1.rotation + + private val a1 = anchor1 - node1.pos + private val a2 = anchor2 - node2.pos + private val initRotation1 = node1.rotation + private val initRotation2 = node2.rotation + + def connection1 = (a1 rotate (node1.rotation - initRotation1)) + node1.pos + def connection2 = (a2 rotate (node2.rotation - initRotation2)) + node2.pos + + /**Relative Position der Bindungspunkte.*/ + def x = connection2 - connection1 + + /**Relative Geschwindigkeit der Bindungspunkte.*/ + def v = node2.velocityOfPoint(connection2) - node1.velocityOfPoint(connection1) + + + def correctVelocity(h: Double) = { + correctLinear(h) + //correctAngular(h) + } + + def correctLinear(h: Double) = { + val x = this.x.unit //relativer Abstand + val n0 = x.leftNormal + val v = this.v //relative Geschwindigkeit + val r1 = (connection1 - node1.pos) //Abstand Punkt-Schwerpunkt, Koerper 1 + val r2 = (connection2 - node2.pos) //Abstand Punkt-Schwerpunkt, Koerper 2 + val cr1 = r1 cross n0 //Kreuzprodukt + val cr2 = r2 cross n0 //Kreuzprodukt + val Cdot = n0 dot v + val invMass = 1/node1.mass + 1/node1.I * cr1 * cr1 + 1/node2.mass + 1/node2.I * cr2 * cr2 + val m = if (invMass == 0.0) 0.0 else 1/invMass + val impulse = -n0 * m * Cdot + node1.applyImpulse(-impulse, connection1) + node2.applyImpulse(impulse, connection2) + } + + //J=[-1,1] + + def correctAngular(h: Double) = { + val w = node2.angularVelocity - node1.angularVelocity + val Cdot = w + val invMass = node1.I + node2.I + val m = 1 / invMass + val lambda = m * Cdot + node1.angularVelocity += lambda / node1.I + node2.angularVelocity += -lambda / node2.I + } + + def correctPosition(h: Double) = { + /* + val x = this.x.unit //relativer Abstand + val n0 = x.leftNormal + val v = this.v //relative Geschwindigkeit + val r1 = (connection1 - node1.pos) //Abstand Punkt-Schwerpunkt, Koerper 1 + val r2 = (connection2 - node2.pos) //Abstand Punkt-Schwerpunkt, Koerper 2 + val cr1 = r1 cross n0 //Kreuzprodukt + val cr2 = r2 cross n0 //Kreuzprodukt + val C = n0 dot x + val invMass = 1/node1.mass + 1/node1.I * cr1 * cr1 + 1/node2.mass + 1/node2.I * cr2 * cr2 + val m = if (invMass == 0.0) 0.0 else 1/invMass + val impulse = -n0 * m * C + node1.pos += -impulse + node1.rotation += -impulse cross r1 + node2.pos += impulse + node2.rotation += impulse cross r2 + + val relOmega = node2.angularVelocity - node2.angularVelocity + val invMassOmega = node1.I + node2.I + val mOmega = if (invMassOmega == 0.0) 0.0 else 1/invMassOmega + val Crot = node2.rotation - node2.rotation + angle + node1.rotation += mOmega * Crot + node2.rotation += -mOmega * Crot + */ + } +} diff --git a/src/sims/materials/Material.scala b/src/sims/materials/Material.scala new file mode 100644 index 0000000..b05e082 --- /dev/null +++ b/src/sims/materials/Material.scala @@ -0,0 +1,7 @@ +package sims.materials + +trait Material { + val density: Double + val restitution: Double + val friction: Double +} diff --git a/src/sims/materials/Rubber.scala b/src/sims/materials/Rubber.scala new file mode 100644 index 0000000..b408d2d --- /dev/null +++ b/src/sims/materials/Rubber.scala @@ -0,0 +1,5 @@ +package sims.materials + +object Rubber { + +} diff --git a/src/sims/materials/Steel.scala b/src/sims/materials/Steel.scala new file mode 100644 index 0000000..71594b8 --- /dev/null +++ b/src/sims/materials/Steel.scala @@ -0,0 +1,5 @@ +package sims.materials + +object Steel { + +} diff --git a/src/sims/prefabs/Ragdoll.scala b/src/sims/prefabs/Ragdoll.scala index ad58653..00e4b8d 100644 --- a/src/sims/prefabs/Ragdoll.scala +++ b/src/sims/prefabs/Ragdoll.scala @@ -38,6 +38,6 @@ class Ragdoll(position: Vector2D) extends Prefab { val shoulder1 = RevoluteJoint(headTorso, upperArm1, position + Vector2D(0, -0.16)) val shoulder2 = RevoluteJoint(headTorso, upperArm2, position + Vector2D(0, -0.16)) - override val joints = List(shoulder1, shoulder2) + override val joints = Nil //List(shoulder1, shoulder2) } -- cgit v1.2.3