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 } }