package edu.colorado.phet.movingman.ladybug
import java.awt.geom.Rectangle2D
import LadybugUtil._
import java.lang.Math._
abstract case class MotionType(name: String) {
def update(dt: Double, model: LadybugModel)
}
object LadybugMotionModel {
val MANUAL = new MotionType("manual") {
def update(dt: Double, model: LadybugModel) = {}
}
val LINEAR = new MotionType("linear") {
def update(dt: Double, model: LadybugModel) = {
val speed = 0.3
def step = model.ladybug.translate(new Vector2D(model.ladybug.getAngle) * speed)
step
val bounds = new Rectangle2D.Double(-10, -10, 20, 20)
if (!bounds.contains(model.ladybug.getPosition)) {
model.ladybug.setAngle(model.ladybug.getAngle + PI + (random * 0.8 - 0.4) * PI / 2)
step
step
}
}
}
val CIRCULAR = new MotionType("circular") {
def update(dt: Double, model: LadybugModel) = {
val distFromCenter = model.ladybug.getPosition.magnitude
val radius = 7.5
val distFromRing = abs(distFromCenter - radius)
val dx = radius - distFromCenter;
val speed = 0.3
if (distFromRing > speed + 1E-6) {
val velocity = new Vector2D(model.ladybug.getPosition.getAngle) * speed * (if (dx < 0) -1 else 1)
model.ladybug.translate(velocity)
} else {
//move in a circle
val angle = model.ladybug.getPosition.getAngle
val r = model.ladybug.getPosition.magnitude
val newAngle = angle + PI / 64 * 1.3;
model.ladybug.setPosition(new Vector2D(newAngle) * r)
}
}
}
val ELLIPSE = new MotionType("ellipse") {
var t = 0.0
def update(dt: Double, model: LadybugModel) = {
val a = 8
val b = 5
val pos = model.ladybug.getPosition
val ladybugC = pos.x * pos.x / a * a + pos.y * pos.y / b * b
t = t + 0.08
model.ladybug.setPosition(new Vector2D(a * cos(t), b * sin(t)))
}
}
}
class LadybugMotionModel extends ObservableS {
private var _motionType = LadybugMotionModel.MANUAL
def motion: MotionType = _motionType
def motion_=(x: MotionType) = {
_motionType = x
notifyListeners
}
def update(dt: Double, model: LadybugModel) = {
_motionType.update(dt, model)
}
def resetAll() {
motion = LadybugMotionModel.MANUAL
}
}