Permalink
Browse files

figured out angular velocity and rotating line + stationary circle co…

…llisions
  • Loading branch information...
1 parent 58d6d45 commit a421701df80ee34f5f75a9fbbb71cbe79a6cab68 @simianarmy committed Feb 5, 2012
@@ -1,3 +1,6 @@
+# @module bitmapDemo
+
+#= require ./mylibs/Math
#= require ./mylibs/Polygon
#= require ./mylibs/collisions
@@ -75,7 +78,7 @@ bitmapDemo = (bitmap) ->
lastRot += 45
context.save()
context.translate(imgX, imgY)
- context.rotate degreesToRadians(lastRot)
+ context.rotate Math.degreesToRadians(lastRot)
context.drawImage(img, 0, 0)
context.restore()
@@ -85,7 +88,7 @@ bitmapDemo = (bitmap) ->
context.save()
context.translate(imgX, imgY)
context.scale 0.5, 0.5
- context.rotate degreesToRadians(lastRot)
+ context.rotate Math.degreesToRadians(lastRot)
context.drawImage(img, 0, 0)
context.restore()
@@ -17,14 +17,18 @@ Canvas = (() ->
@width = canvasEl.width
@height = canvasEl.height
+ context = () -> @ctxt
+
# Set the origin of the canvas
# @param {String} id (topleft | bottomleft)
setOrigin = (id) ->
if id == 'topleft'
# translate world for origin at bottom left
@ctxt.scale(1, -1)
@ctxt.translate(0, -@height)
-
+ else
+ # bottom left is default
+
# Draw a circle on the canvas
# @param {Circle} c a Circle object
drawCircle = (c) ->
@@ -96,6 +100,7 @@ Canvas = (() ->
drawLine: drawLine
drawEllipse: drawEllipse
inContext: inContext
+ context: context
rotate: rotate
translate: translate
clear: clear
@@ -0,0 +1,28 @@
+# @module Math
+#
+# Extensions to the built-in Math module
+
+#= require ./vec
+
+# angularVelocity
+#
+# Angular velocity of a particle in 2 dimensions
+# @param {Vector} v velocity vector of the particle
+# @param {Vector} r position vector of the particle (from origin or rotation)
+# @param {Float} theta angle of rotation (in radians)
+# @return {Float} the angular velocity
+Math.angularVelocity = (v, r, theta) ->
+ (v.mag() * Math.sin(theta)) / r.mag()
+
+# Returns a random float between min and max
+# Using Math.round() will give you a non-uniform distribution!
+Math.getRandom = (min, max) ->
+ (Math.random() * (max - min + 1)) + min
+
+# Returns a random integer between min and max
+# Using Math.round() will give you a non-uniform distribution!
+Math.getRandomInt = (min, max) ->
+ Math.floor(Math.random() * (max - min + 1)) + min
+
+Math.degreesToRadians = (degrees) ->
+ degrees * Math.PI / 180
@@ -1,5 +1,6 @@
-# PoolTable.coffee
+# @module PoolTable
+#= require ./Math
#= require ./vec
#= require ./collisions
#= require ./Line
@@ -319,7 +320,7 @@ PoolTable = (ctxt, opts) ->
context.save()
context.translate balls[0].pos.e(1), balls[0].pos.e(2)
- context.rotate degreesToRadians(cueRotDegrees)
+ context.rotate Math.degreesToRadians(cueRotDegrees)
context.translate ogCuePos.e(1), ogCuePos.e(2)
context.drawImage(cueImg, 0, 0, cueImg.width, cueImg.height)
context.restore()
@@ -9,9 +9,14 @@ class Shape
@mass = @efficiency = 1.0
@collisionNormal = null # vector
@[x] = val for x, val of opts
+ # initial speed, angular speed, etc
@velocity ?= Vector.Zero(3)
@displacement ?= Vector.Zero(3)
@direction ?= Vector.Zero(3)
+ @speed ?= 0
+ @rotation ?= 0
+ @angSpeed ?= 0
+ @rotDirection ?= 1
move: (vec) ->
@pos = @pos.add(vec)
@@ -20,6 +25,20 @@ class Shape
y: -> @pos.e(2)
z: -> @pos.e(3)
+ angularDirection: -> @rotDirection
+
+ # calculate shape's angular velocity
+ # @return {Number} pseudovector omega with sign dependent
+ # on direction of rotation around axis (clockwiseNormal)
+ angularVelocity: ->
+ @angularDirection() * @angSpeed
+
+ # set the shape's angular velocity
+ # @param {Number} v degrees/second
+ setAngularVelocity: (v) ->
+ @rotDirection = if v > 0 then 1 else -1
+ @angSpeed = Math.abs(v) # * 180 / Math.PI
+
# prototype properties
toString: ->
kvs = for key, val of @ when val? and typeof(val) != 'function'
@@ -1,8 +1,9 @@
# @module scene
# Module for moving circles in a box
-#= require 'libs/raphael-min'
+#= require libs/raphael-min
#= require ./vec
+#= require ./Math
#= require ./collisions
#= require ./Line
#= require ./Circle
@@ -63,15 +64,15 @@ scene = (opts) ->
# Return a random circle color
randomCircleColor = ->
- CIRCLE_COLORS[getRandomInt(1, CIRCLE_COLORS.length)-1]
+ CIRCLE_COLORS[Math.getRandomInt(1, CIRCLE_COLORS.length)-1]
# Return a y-value for a circle
circleY = ->
- if freeY then getRandom(-MAX_VELOCITY_Y, MAX_VELOCITY_Y) else 0
+ if freeY then Math.getRandom(-MAX_VELOCITY_Y, MAX_VELOCITY_Y) else 0
# Create and return a new (free) circle
createFreeCircle = (x, y, i) ->
- velx = getRandom(-MAX_VELOCITY_X, MAX_VELOCITY_X)
+ velx = Math.getRandom(-MAX_VELOCITY_X, MAX_VELOCITY_X)
new Circle(x, y, 0, {
radius: CIRCLE_RADIUS
velocity: Vector.create([velx, circleY(), 0])
@@ -91,7 +92,7 @@ scene = (opts) ->
if diff > 0
# Add balls
for i in [1..diff]
- circles.push createFreeCircle(getRandom(0, bw), bh/2, i)
+ circles.push createFreeCircle(Math.getRandom(0, bw), bh/2, i)
else
# remove balls
circles.pop() for i in [1..(circles.length-nballs)]
@@ -2,7 +2,8 @@
#= require ../libs/sylvester
-collisions = ->
+collisions = {}
+collisions = (->
# constants
collisions.NONE = -1
collisions.EMBEDDED = -2
@@ -106,6 +107,39 @@ collisions = ->
t = intersectionTime(c.pos.add(r), c.displacement, wall.pos, wall.vec)
[t, collisionNormal]
+ # Check for collision between rotating line and circle
+ # Anglular values should be in radians
+ # @param {Number} theta0 angle of starting position of line from the vertical
+ # @param {Number} omega angular velocity of rotating line
+ # @param {Number} l line length
+ # @param {Number} r ball radius
+ # @param {Number} d distance of line origin to ball center
+ # @param {Number} alpha angle of vertical and line to ball center
+ angularCollisionLineCircle = (theta0, omega, l, r, d, alpha) ->
+ return collisison.NONE if d > l + r
+ return collisions.EMBEDDED if d < r
+ k = 1
+ # move into a calculation within the range of [0,2pi]
+ alpha -= theta0
+ if omega < 0
+ omega = -omega
+ alpha = -alpha
+ k = -1
+
+ pi2 = Math.PI * 2
+ while alpha < 0
+ alpha += pi2
+ while alpha > pi2
+ alpha -= pi2
+
+ # check if there is a possible collision
+ # return collisions.NONE if alpha > omega
+ # now perform the appropriate collision check
+ if d*d <= (l*l + r*r)
+ (alpha - k * Math.asin(r / d)) / omega
+ else
+ (alpha - k * Math.acos((l*l + d*d - r*r) / (2*l*d))) / omega
+
isImpendingCollision = (ts) ->
0 < ts <= 1
@@ -321,8 +355,10 @@ collisions = ->
isImpendingCollision,
resolveCollision,
resolveInelasticCollisionFixed,
+ angularCollisionLineCircle,
pointInTriangle,
pointInPolygon}
-
+)()
+
root = exports ? window
-root.collisions = collisions()
+root.collisions = collisions
@@ -9,7 +9,7 @@
# isClockwise
#
-# Determines if object at p with velocity v is moving clockwise about the origin
+# Determines if object starts at p with velocity v is moving clockwise about the origin
# @returns {Boolean}
Vector.isClockwise = (v, p) ->
n = p.clockwiseNormal()
@@ -93,4 +93,3 @@ Vector::clockwiseNormal = ->
Vector::moment = (p) ->
@clockwiseNormal().dot(p)
-
View
@@ -31,21 +31,3 @@ window.requestAnimFrame = (function() {
window.setTimeout(callback, 1000/60);
};
})();
-
-// Returns a random float between min and max
-// Using Math.round() will give you a non-uniform distribution!
-function getRandom(min, max)
-{
- return (Math.random() * (max - min + 1)) + min;
-}
-
-// Returns a random integer between min and max
-// Using Math.round() will give you a non-uniform distribution!
-function getRandomInt(min, max)
-{
- return Math.floor(Math.random() * (max - min + 1)) + min;
-}
-
-function degreesToRadians(degrees) {
- return degrees * Math.PI / 180
-}
Oops, something went wrong.

0 comments on commit a421701

Please sign in to comment.