vibrating ball

Started by
0 comments, last by BBHudson 17 years, 8 months ago
Its not as painfull as it sounds! My collision detection is working well, but for some reason the ball never actually sits plum onto a flat surface and rolls. It kind of lightly vibrates whilst rolling, a pixel above the line or so. It is a 2D game from a flash project. Here is the code:

var yVelocity = 0;
var YTERMINALVEL = 30;
var xVelocity = 0;
var XTERMINALVEL = 30;
var collisionPointX = 0;
var collisionPointY = 0;

onEnterFrame = function()
{
	//make a dummy ball
	tempBall = {};
	tempBall = this;
	tempBall.radius = (this._width / 2);

	tempBall = _root.freq_applyGravity(tempBall);
	collisionTests();
	_root.freq_move(tempBall);
}

function collisionTests()
{
	var i = 0;
	var lines = _root.collideLines;
	for(i=0;i<lines.length;i++)
	{
		
		var theLine = lines;
		frames = getFrames(theLine,tempBall);
		if((frames < 1)&&(frames > 0))
		{
			react(theLine);
		}
	}
}

function react(tempLine)
{
		var lineDecay = 0.5;
		tempLine.angle = Math.atan2(tempLine.m*1,1);
		var alpha = tempLine.angle;
		var cosAlpha = Math.cos(alpha);
		var sinAlpha = Math.sin(alpha);
		//get the x and y velocities of the ball
		var vyi = tempBall.yVelocity;
		var vxi = tempBall.xVelocity;
		//project the x and y velocities onto the line of action
		var vyip = vyi*cosAlpha-vxi*sinAlpha;
		//project the x and y velocities onto the line
		var vxip = vxi*cosAlpha+vyi*sinAlpha;
		//reverse the velocity along the line of action
		var vyfp = -vyip*lineDecay;
		var vxfp = vxip;
		//translate back to Flash's x and y axes
		var vyf = vyfp*cosAlpha+vxfp*sinAlpha;
		var vxf = vxfp*cosAlpha-vyfp*sinAlpha;
		//set the velocities of the ball based from the results
		tempBall.xVelocity = vxf;
		tempBall.yVelocity = vyf;
		tempBall.tempx = point._x+point.xVelocity;
		tempBall.tempy = point._y+point.yVelocity;
		moveToContactPoint();
}

//how long will it take to hit a line
function getFrames(tempLine, point) 
{
		//the y intercept of the ball trajectory
		var slope2 = point.yVelocity/point.xVelocity;
		if (slope2 == Number.POSITIVE_INFINITY) 
		{
			var slope2 = 1000000;
		} 
		else if (slope2 == Number.NEGATIVE_INFINITY) 
		{
			var slope2 = -1000000;
		}
		var b2 = point._y-slope2*point._x;
		
		//intersection point
		tempLine.angle = Math.atan2(tempLine.m*1,1);
		tempLine.slope = Math.tan(tempLine.angle);
		var x = (b2-tempLine.b)/(tempLine.slope-slope2);
		var y = tempLine.slope*x+tempLine.b;
		//the angle that the ball is moving
		var theta = Math.atan2(point.yVelocity, point.xVelocity);
		//the difference between the angle of the line and of the ball trajectory
		tempLine.angle = Math.atan2(tempLine.m*1,1);
		var gamma = theta-tempLine.angle;
		//modify x and y
		var sinGamma = Math.sin(gamma);
		var r = (point.radius)/sinGamma;
		//the ball's position at point of contact
		var x = x-r*Math.cos(theta);
		var y = y -r*Math.sin(theta);
		collisionPointX = x;
		collisionPointY = y;
		//Now find how long it will take to
		//get to the point of contact
		var dis = Math.sqrt((x-point._x)*(x-point._x)+(y-point._y)*(y-point._y));
		var vel = Math.sqrt(point.xVelocity*point.xVelocity+point.yVelocity*point.yVelocity);
		var frames = dis/vel;
		//now check to see if point of contact is on the line segment
		var slope2a = -1/tempLine.slope;
		var b2a = y-slope2a*x;
		//point of contact
		var xa = (tempLine.b-b2a)/(slope2a-tempLine.slope);
		var ya = slope2a*xa+b2a;
		if ((xa>tempLine.lowX && xa<tempLine.highX) || (xa<tempLine.lowX && xa>tempLine.highX) || ((ya>tempLine.lowY && ya<tempLine.highY) || (ya<tempLine.lowY && ya>tempLine.highY))) {
			//within segment boundaries
		} 
		else 
			//not within segment boundaries so set frames high
			var frames = 1000;
	return frames;
}

function moveToContactPoint()
{
	tempBall.x = collisionPointX;
	tempBall.y = collisionPointY;
}

Advertisement
I'm not too great at reading code so I don't know if this is what's causing it in your own program, but there is a common phenomena in collision models that sounds like just what you are describing. Basically if you drop a ball onto a hard surface it will bounce a few times then come to rest, but in a mathematical model of this, the ball will theoretically bounce infinitely many times (and only at time infinite will it actually be at rest). So anyway in a model you may see an object that is supposed to be at rest fluxuate up and down by a very small amount - this is made worse since a very small change in distance can result in a visual displacement of a single pixel due to rounding errors, which looks bigger than it should be. If you decide on some fundamental "smallest" velocity for your objects then you can set anything below this value to be at rest.

This topic is closed to new replies.

Advertisement