summaryrefslogtreecommitdiff
path: root/src/main/scala/graphyx/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/graphyx/graphics')
-rw-r--r--src/main/scala/graphyx/graphics/Drawable.scala118
-rw-r--r--src/main/scala/graphyx/graphics/GraphicalAABB.scala18
-rw-r--r--src/main/scala/graphyx/graphics/GraphicalBody.scala42
-rw-r--r--src/main/scala/graphyx/graphics/GraphicalCircle.scala22
-rw-r--r--src/main/scala/graphyx/graphics/GraphicalCollision.scala18
-rw-r--r--src/main/scala/graphyx/graphics/GraphicalDistanceJoint.scala19
-rw-r--r--src/main/scala/graphyx/graphics/GraphicalJoint.scala12
-rw-r--r--src/main/scala/graphyx/graphics/GraphicalObject.scala15
-rw-r--r--src/main/scala/graphyx/graphics/GraphicalPair.scala18
-rw-r--r--src/main/scala/graphyx/graphics/GraphicalRectangle.scala18
-rw-r--r--src/main/scala/graphyx/graphics/GraphicalRegularPolygon.scala19
-rw-r--r--src/main/scala/graphyx/graphics/GraphicalRevoluteJoint.scala20
-rw-r--r--src/main/scala/graphyx/graphics/GraphicalShape.scala15
-rw-r--r--src/main/scala/graphyx/graphics/GraphicalSpringJoint.scala18
-rw-r--r--src/main/scala/graphyx/graphics/GraphicalWorld.scala28
-rw-r--r--src/main/scala/graphyx/graphics/Parser.scala35
-rw-r--r--src/main/scala/graphyx/graphics/Scene.scala24
17 files changed, 459 insertions, 0 deletions
diff --git a/src/main/scala/graphyx/graphics/Drawable.scala b/src/main/scala/graphyx/graphics/Drawable.scala
new file mode 100644
index 0000000..e1757f7
--- /dev/null
+++ b/src/main/scala/graphyx/graphics/Drawable.scala
@@ -0,0 +1,118 @@
+/*
+ * Graphyx
+ * copyright (c) 2009 Jakob Odersky
+ * made available under the MIT License
+*/
+
+package graphyx.graphics
+
+import sims.geometry._
+
+/**Enthaelt Methoden und Felder fuer graphische Darstellungen.
+ * Alle Klassen die dieses Trait implementieren koennen graphisch dargestellt werden.*/
+trait Drawable {
+
+ /**Java Graphics Objekt zur graphischen Darstellung*/
+ var g: java.awt.Graphics2D = _
+
+ /**Anzahl von Pixeln pro Meter.*/
+ var ppm: Double = 39.37007874015748 * 96 //ppm = i/m * p/i
+
+ /**Skala in der die graphischen Objekte gezeichnet werden.*/
+ var scale: Double = 1.0/100.0
+
+ /**Hoehe des Fensters in Pixeln.*/
+ var windowHeight = 0
+
+ /**Korrigiert einen Y-Wert in Bildschirmkoordinaten zu seinem kartesischen Aequivalent.
+ * @param y zu korrigierender Wert*/
+ def correctY(y: Double) = windowHeight - y
+
+ /**Malt eine Linie auf <code>g</code>.
+ * @param startPoint Startpunkt in Weltkoordinaten
+ * @param endPoint Endpunkt in Weltkoordinaten*/
+ def drawLine(startPoint: Vector2D, endPoint: Vector2D) = {
+ val x1 = startPoint.x * scale * ppm
+ val y1 = correctY(startPoint.y * scale * ppm)
+ val x2 = endPoint.x * scale * ppm
+ val y2 = correctY(endPoint.y * scale * ppm)
+ g.drawLine(x1.toInt, y1.toInt, x2.toInt, y2.toInt)
+ }
+
+ /**Malt ein massives Polygon auf <code>g</code>.
+ * @param points Eckpunkte des Polygons in Weltkoordinaten*/
+ def fillPolygon(points: Seq[Vector2D]) = {
+ val xs = points map ((v: Vector2D) => (v.x * scale * ppm).toInt)
+ val ys = points map ((v: Vector2D) => correctY((v.y) * scale * ppm).toInt)
+ g.fillPolygon(xs.toArray, ys.toArray, points.length)
+ }
+
+ /**Malt ein Polygon auf <code>g</code>.
+ * @param points Eckpunkte des Polygons in Weltkoordinaten*/
+ def drawPolygon(points: Seq[Vector2D]) = {
+ val xs = points map ((v: Vector2D) => (v.x * scale * ppm).toInt)
+ val ys = points map ((v: Vector2D) => correctY((v.y) * scale * ppm).toInt)
+ g.drawPolygon(xs.toArray, ys.toArray, points.length)
+ }
+
+ /**Malt einen massiven Kreis auf <code>g</code>.
+ * @param center Mitte des Kreises in Weltkoordinaten
+ * @param radius Radius des Kreises*/
+ def fillCircle(center: Vector2D, radius: Double) = {
+ g.fillOval(((center.x - radius) * scale * ppm).toInt,
+ correctY((center.y + radius) * scale * ppm).toInt,
+ (radius * scale * ppm * 2).toInt,
+ (radius * scale * ppm * 2).toInt)
+ }
+
+ /**Malt einen Kreis auf <code>g</code>.
+ * @param center Mitte des Kreises in Weltkoordinaten
+ * @param radius Radius des Kreises*/
+ def drawCircle(center: Vector2D, radius: Double) = {
+ g.drawOval(((center.x - radius) * scale * ppm).toInt,
+ correctY((center.y + radius) * scale * ppm).toInt,
+ (radius * scale * ppm * 2).toInt,
+ (radius * scale * ppm * 2).toInt)
+ }
+
+ /**Malt einen Punkt auf <code>g</code>.
+ * <p>
+ * Der Punkt wird von einem Kreis umgeben.
+ * @param point Punkt in Weltkoordinaten*/
+ def drawPoint(point: Vector2D) = {
+ val radius = 4 //in pixel
+ g.drawLine((point.x * scale * ppm).toInt,
+ correctY(point.y * scale * ppm).toInt - radius,
+ (point.x * scale * ppm).toInt,
+ correctY(point.y * scale * ppm).toInt + radius)
+ g.drawLine((point.x * scale * ppm).toInt - radius,
+ correctY(point.y * scale * ppm).toInt,
+ (point.x * scale * ppm).toInt + radius,
+ correctY(point.y * scale * ppm).toInt)
+ g.drawOval((point.x * scale * ppm).toInt - radius,
+ correctY(point.y * scale * ppm).toInt - radius,
+ (radius * 2).toInt,
+ (radius * 2).toInt)
+
+ }
+
+
+ /**Malt einen Vektor auf <code>g</code>.
+ * @param v Vektor in Weltkoordinaten
+ * @param p Ursprungspunkt in Weltkoordinaten
+ */
+ def drawVector(v: Vector2D, p: Vector2D) = {
+ if (!v.isNull) {
+ val ep = p + v
+ val a1 = ep - ((v.unit rotate (math.Pi / 6)) * 0.08)
+ val a2 = ep - ((v.unit rotate (-math.Pi / 6)) * 0.08)
+
+ g.drawLine((p.x * scale * ppm).toInt, correctY(p.y * scale * ppm).toInt, (ep.x * scale * ppm).toInt, correctY(ep.y * scale * ppm).toInt)
+ g.drawLine((a1.x * scale * ppm).toInt, correctY(a1.y * scale * ppm).toInt, (ep.x * scale * ppm).toInt, correctY(ep.y * scale * ppm).toInt)
+ g.drawLine((a2.x * scale * ppm).toInt, correctY(a2.y * scale * ppm).toInt, (ep.x * scale * ppm).toInt, correctY(ep.y * scale * ppm).toInt)
+ }
+ }
+
+ /**Stellt das graphische Objekt dar.*/
+ def draw(): Unit
+}
diff --git a/src/main/scala/graphyx/graphics/GraphicalAABB.scala b/src/main/scala/graphyx/graphics/GraphicalAABB.scala
new file mode 100644
index 0000000..cb3694b
--- /dev/null
+++ b/src/main/scala/graphyx/graphics/GraphicalAABB.scala
@@ -0,0 +1,18 @@
+/*
+ * Graphyx
+ * copyright (c) 2009 Jakob Odersky
+ * made available under the MIT License
+*/
+
+package graphyx.graphics
+
+import sims.collision._
+class GraphicalAABB(val real: AABB) extends AABB(real.minVertex, real.maxVertex) with GraphicalObject {
+ override def draw() = {
+ g.setColor(java.awt.Color.BLACK)
+ g.drawRect((minVertex.x * scale * ppm).toInt,
+ correctY(maxVertex.y * scale * ppm).toInt,
+ ((maxVertex - minVertex).x * scale * ppm).toInt,
+ ((maxVertex - minVertex).y * scale * ppm).toInt)
+ }
+}
diff --git a/src/main/scala/graphyx/graphics/GraphicalBody.scala b/src/main/scala/graphyx/graphics/GraphicalBody.scala
new file mode 100644
index 0000000..c78ea51
--- /dev/null
+++ b/src/main/scala/graphyx/graphics/GraphicalBody.scala
@@ -0,0 +1,42 @@
+/*
+ * Graphyx
+ * copyright (c) 2009 Jakob Odersky
+ * made available under the MIT License
+*/
+
+package graphyx.graphics
+
+import sims.dynamics._
+
+case class GraphicalBody(real: Body) extends GraphicalObject {
+ val pos = real.pos
+ val fixed = real.fixed
+ val monitor = real.monitor
+ def draw() = {
+ val radius = 4
+ val posX = (pos.x * scale * ppm).toInt
+ val posY = correctY(pos.y * scale * ppm).toInt
+ g.setColor(java.awt.Color.yellow)
+ g.fillArc(posX - radius,
+ posY - radius,
+ (radius * 2).toInt,
+ (radius * 2).toInt,
+ 0, 90)
+ g.fillArc(posX - radius,
+ posY - radius,
+ (radius * 2).toInt,
+ (radius * 2).toInt,
+ 180, 90)
+ g.setColor(java.awt.Color.black)
+ g.fillArc(posX - radius,
+ posY - radius,
+ (radius * 2).toInt,
+ (radius * 2).toInt,
+ 90, 90)
+ g.fillArc(posX - radius,
+ posY - radius,
+ (radius * 2).toInt,
+ (radius * 2).toInt,
+ 270, 90)
+ }
+}
diff --git a/src/main/scala/graphyx/graphics/GraphicalCircle.scala b/src/main/scala/graphyx/graphics/GraphicalCircle.scala
new file mode 100644
index 0000000..77b038c
--- /dev/null
+++ b/src/main/scala/graphyx/graphics/GraphicalCircle.scala
@@ -0,0 +1,22 @@
+/*
+ * Graphyx
+ * copyright (c) 2009 Jakob Odersky
+ * made available under the MIT License
+*/
+
+package graphyx.graphics
+
+import sims._
+import geometry._
+import dynamics._
+class GraphicalCircle(val real: Circle) extends Circle(real.radius, real.density) with GraphicalShape{
+ override def draw() = {
+ //val b = math.min(density / 100 * 255, 255)
+ //g.setColor(new java.awt.Color(0,0,255, b.toInt))
+ g.setColor(java.awt.Color.blue)
+ fillCircle(pos, real.radius)
+ g.setColor(java.awt.Color.BLACK)
+ drawCircle(pos, real.radius)
+ this.drawLine(pos, pos + (Vector2D.i rotate rotation) * real.radius)
+ }
+}
diff --git a/src/main/scala/graphyx/graphics/GraphicalCollision.scala b/src/main/scala/graphyx/graphics/GraphicalCollision.scala
new file mode 100644
index 0000000..5589f8c
--- /dev/null
+++ b/src/main/scala/graphyx/graphics/GraphicalCollision.scala
@@ -0,0 +1,18 @@
+/*
+ * Graphyx
+ * copyright (c) 2009 Jakob Odersky
+ * made available under the MIT License
+*/
+
+package graphyx.graphics
+
+import sims.collision._
+
+case class GraphicalCollision(real: Collision) extends GraphicalObject{
+ val points = real.points
+ val normal = real.normal
+ def draw() = {
+ g.setColor(java.awt.Color.GREEN)
+ for (p <- points) {drawPoint(p); drawVector(normal, p)}
+ }
+} \ No newline at end of file
diff --git a/src/main/scala/graphyx/graphics/GraphicalDistanceJoint.scala b/src/main/scala/graphyx/graphics/GraphicalDistanceJoint.scala
new file mode 100644
index 0000000..4a6e49d
--- /dev/null
+++ b/src/main/scala/graphyx/graphics/GraphicalDistanceJoint.scala
@@ -0,0 +1,19 @@
+/*
+ * Graphyx
+ * copyright (c) 2009 Jakob Odersky
+ * made available under the MIT License
+*/
+
+package graphyx.graphics
+
+import sims.dynamics.joints._
+
+case class GraphicalDistanceJoint(real: DistanceJoint) extends GraphicalJoint {
+ val connection1 = real.connection1
+ val connection2 = real.connection2
+
+ def draw() = {
+ g.setColor(java.awt.Color.BLACK)
+ drawLine(connection1, connection2)
+ }
+}
diff --git a/src/main/scala/graphyx/graphics/GraphicalJoint.scala b/src/main/scala/graphyx/graphics/GraphicalJoint.scala
new file mode 100644
index 0000000..27d4f83
--- /dev/null
+++ b/src/main/scala/graphyx/graphics/GraphicalJoint.scala
@@ -0,0 +1,12 @@
+/*
+ * Graphyx
+ * copyright (c) 2009 Jakob Odersky
+ * made available under the MIT License
+*/
+
+package graphyx.graphics
+
+import sims.dynamics.joints._
+trait GraphicalJoint extends GraphicalObject{
+ val real: Joint
+}
diff --git a/src/main/scala/graphyx/graphics/GraphicalObject.scala b/src/main/scala/graphyx/graphics/GraphicalObject.scala
new file mode 100644
index 0000000..3c56de6
--- /dev/null
+++ b/src/main/scala/graphyx/graphics/GraphicalObject.scala
@@ -0,0 +1,15 @@
+/*
+ * Graphyx
+ * copyright (c) 2009 Jakob Odersky
+ * made available under the MIT License
+*/
+
+package graphyx.graphics
+
+/**Only copies functional info! (e.g. Graphical world does not include shapes, bodies).*/
+trait GraphicalObject extends Drawable{
+
+ /**Pointer to real object.*/
+ val real: AnyRef
+ def draw(): Unit
+}
diff --git a/src/main/scala/graphyx/graphics/GraphicalPair.scala b/src/main/scala/graphyx/graphics/GraphicalPair.scala
new file mode 100644
index 0000000..72e72ae
--- /dev/null
+++ b/src/main/scala/graphyx/graphics/GraphicalPair.scala
@@ -0,0 +1,18 @@
+/*
+ * Graphyx
+ * copyright (c) 2009 Jakob Odersky
+ * made available under the MIT License
+*/
+
+package graphyx.graphics
+
+import sims.collision._
+case class GraphicalPair(real: Pair) extends GraphicalObject{
+ val pos1 = real.s1.pos
+ val pos2 = real.s2.pos
+
+ def draw() = {
+ g.setColor(java.awt.Color.ORANGE)
+ drawLine(pos1, pos2)
+ }
+}
diff --git a/src/main/scala/graphyx/graphics/GraphicalRectangle.scala b/src/main/scala/graphyx/graphics/GraphicalRectangle.scala
new file mode 100644
index 0000000..05dfa76
--- /dev/null
+++ b/src/main/scala/graphyx/graphics/GraphicalRectangle.scala
@@ -0,0 +1,18 @@
+/*
+ * Graphyx
+ * copyright (c) 2009 Jakob Odersky
+ * made available under the MIT License
+*/
+
+package graphyx.graphics
+
+import sims._
+import sims.dynamics._
+class GraphicalRectangle(val real: Rectangle) extends Rectangle(real.halfWidth, real.halfHeight, real.density) with GraphicalShape {
+ override def draw() = {
+ g.setColor(java.awt.Color.red)
+ fillPolygon(vertices)
+ g.setColor(java.awt.Color.BLACK)
+ drawPolygon(vertices)
+ }
+} \ No newline at end of file
diff --git a/src/main/scala/graphyx/graphics/GraphicalRegularPolygon.scala b/src/main/scala/graphyx/graphics/GraphicalRegularPolygon.scala
new file mode 100644
index 0000000..fff8a9e
--- /dev/null
+++ b/src/main/scala/graphyx/graphics/GraphicalRegularPolygon.scala
@@ -0,0 +1,19 @@
+/*
+ * Graphyx
+ * copyright (c) 2009 Jakob Odersky
+ * made available under the MIT License
+*/
+
+package graphyx.graphics
+
+import sims._
+import geometry._
+import dynamics._
+class GraphicalRegularPolygon(val real: RegularPolygon) extends RegularPolygon(real.n, real.radius, real.density) with GraphicalShape{
+ override def draw() = {
+ g.setColor(java.awt.Color.orange)
+ fillPolygon(vertices)
+ g.setColor(java.awt.Color.BLACK)
+ drawPolygon(vertices)
+ }
+} \ No newline at end of file
diff --git a/src/main/scala/graphyx/graphics/GraphicalRevoluteJoint.scala b/src/main/scala/graphyx/graphics/GraphicalRevoluteJoint.scala
new file mode 100644
index 0000000..940a862
--- /dev/null
+++ b/src/main/scala/graphyx/graphics/GraphicalRevoluteJoint.scala
@@ -0,0 +1,20 @@
+/*
+ * Graphyx
+ * copyright (c) 2009 Jakob Odersky
+ * made available under the MIT License
+*/
+
+package graphyx.graphics
+
+import sims.geometry._
+import sims.dynamics.joints._
+
+case class GraphicalRevoluteJoint(real: RevoluteJoint) extends GraphicalJoint {
+ val connection1 = real.connection1
+
+ def draw(): Unit = {
+ g.setColor(java.awt.Color.darkGray)
+ drawPoint(connection1)
+ }
+
+}
diff --git a/src/main/scala/graphyx/graphics/GraphicalShape.scala b/src/main/scala/graphyx/graphics/GraphicalShape.scala
new file mode 100644
index 0000000..256c041
--- /dev/null
+++ b/src/main/scala/graphyx/graphics/GraphicalShape.scala
@@ -0,0 +1,15 @@
+/*
+ * Graphyx
+ * copyright (c) 2009 Jakob Odersky
+ * made available under the MIT License
+*/
+
+package graphyx.graphics
+
+import sims.dynamics._
+trait GraphicalShape extends Shape with GraphicalObject{
+ val real: Shape
+ override val uid: Int = real.uid
+ pos = real.pos
+ rotation = real.rotation
+} \ No newline at end of file
diff --git a/src/main/scala/graphyx/graphics/GraphicalSpringJoint.scala b/src/main/scala/graphyx/graphics/GraphicalSpringJoint.scala
new file mode 100644
index 0000000..dbd9d5f
--- /dev/null
+++ b/src/main/scala/graphyx/graphics/GraphicalSpringJoint.scala
@@ -0,0 +1,18 @@
+/*
+ * Graphyx
+ * copyright (c) 2009 Jakob Odersky
+ * made available under the MIT License
+*/
+
+package graphyx.graphics
+
+import sims.dynamics.joints._
+
+case class GraphicalSpringJoint(real: SpringJoint) extends GraphicalJoint {
+ val connection1 = real.connection1
+ val connection2 = real.connection2
+ def draw(): Unit = {
+ g.setColor(java.awt.Color.GRAY)
+ drawLine(connection1, connection2)
+ }
+}
diff --git a/src/main/scala/graphyx/graphics/GraphicalWorld.scala b/src/main/scala/graphyx/graphics/GraphicalWorld.scala
new file mode 100644
index 0000000..abc9cbb
--- /dev/null
+++ b/src/main/scala/graphyx/graphics/GraphicalWorld.scala
@@ -0,0 +1,28 @@
+/*
+ * Graphyx
+ * copyright (c) 2009 Jakob Odersky
+ * made available under the MIT License
+*/
+
+package graphyx.graphics
+
+import sims.dynamics._
+case class GraphicalWorld(real: World){
+ val time = real.time
+ val timeStep = real.timeStep
+ val iterations = real.iterations
+ val overCWarning = real.overCWarning
+ val gravity = real.gravity
+ val monitorResults = for (m <- real.monitors) yield
+ new MonitorResult(m,
+ for (b <- real.bodies.toList; if (b.monitor)) yield (b.uid, m._1, m._2(b))
+ )
+ val monitorFlatResults = for (b <- real.bodies; m <- real.monitors; if (b.monitor)) yield (b.uid, m._1, m._2(b))
+ val enableCollisionDetection = real.enableCollisionDetection
+ val enablePositionCorrection = real.enablePositionCorrection
+}
+
+class MonitorResult (
+ val monitor: (String, Body => Any),
+ val results: List[(Int, String, Any)]
+)
diff --git a/src/main/scala/graphyx/graphics/Parser.scala b/src/main/scala/graphyx/graphics/Parser.scala
new file mode 100644
index 0000000..785d985
--- /dev/null
+++ b/src/main/scala/graphyx/graphics/Parser.scala
@@ -0,0 +1,35 @@
+/*
+ * Graphyx
+ * copyright (c) 2009 Jakob Odersky
+ * made available under the MIT License
+*/
+
+package graphyx.graphics
+
+import sims.collision._
+import sims.dynamics._
+import sims.dynamics.joints._
+object Parser {
+
+ val throwOnUnknown = false
+
+ def toGraphical(real: Shape) = real match {
+ case c: Circle => new GraphicalCircle(c)
+ case r: Rectangle => new GraphicalRectangle(r)
+ case p: RegularPolygon => new GraphicalRegularPolygon(p)
+ case _ => throw new IllegalArgumentException("Cannot cast '" + real.getClass + "' to a graphical object.")
+ }
+
+ def toGraphical(real: Joint) = real match {
+ case j: DistanceJoint => new GraphicalDistanceJoint(j)
+ case j: SpringJoint => new GraphicalSpringJoint(j)
+ case j: RevoluteJoint => new GraphicalRevoluteJoint(j)
+ 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) = new GraphicalCollision(real)
+ def toGraphical(real: Pair) = new GraphicalPair(real)
+ def toGraphical(real: AABB) = new GraphicalAABB(real)
+ def toGraphical(real: Body) = new GraphicalBody(real)
+}
diff --git a/src/main/scala/graphyx/graphics/Scene.scala b/src/main/scala/graphyx/graphics/Scene.scala
new file mode 100644
index 0000000..bb1fd9e
--- /dev/null
+++ b/src/main/scala/graphyx/graphics/Scene.scala
@@ -0,0 +1,24 @@
+/*
+ * Graphyx
+ * copyright (c) 2009 Jakob Odersky
+ * made available under the MIT License
+*/
+
+package graphyx.graphics
+
+import sims.geometry._
+import sims.collision._
+import sims.dynamics._
+import sims.dynamics.joints._
+import collection.mutable._
+
+case class Scene(real: World) {
+ val world: GraphicalWorld = GraphicalWorld(real)
+ val shapes = for (s: Shape <- real.shapes) yield Parser.toGraphical(s)
+ val joints = for (j: Joint <- real.joints) yield Parser.toGraphical(j)
+ val bodies = for (b: Body <- real.bodies) yield Parser.toGraphical(b)
+ val collisions = for (c: Collision <- real.detector.collisions) yield Parser.toGraphical(c)
+ val pairs = for (p: Pair <- real.detector.asInstanceOf[GridDetector].pairs) yield Parser.toGraphical(p)
+ val aabbs = for (s: Shape <- real.shapes) yield Parser.toGraphical(s.AABB)
+ val fps = 0
+}