ball hits a pointy bit, what happens?

Miscellaneous Forums/General Discussion/ball hits a pointy bit, what happens?

First the pic:



OK so you can work out what happens if a ball hits either of the first two walls. Now what if the ball its a CORNER where two walls join?

If my code is moving the ball a certain amount each frame, it is possible that the ball whill move fast enough in a single frame to overlay the point in such a way that it collides with BOTH lines that make up the corner, yes?

So the final angle of the ball merely depends on which line I test first for collision with the ball (assuming I don't test any other lines after the first collision is detected). And if I test BOTH lines for collision and change the final angle of the ball twice, it will have both x,y directions reversed, thus will come back in the same direction!

Neither seems realistic because in "real life" where there is no "framerate" it would ALWAYS hit one sooner than the other because it would never "overlap" the point (ignoring elasticity etc).

So there may be a way to send a vector in the direction of the ball movement and test which one of the lines it hits first, before the ball actually hits. Then move the ball to the exact point of contact and calc the correct exit angle.

What do you think? Is it too perfectionist and should I just pick the first one I detect in an overlap condition?

Don't those walls share a corner? If it hits right on the point then shouldn't it rebound along it's own path or you can simply randomise which way it'll bounce. If it hits the end of one line it'll be the side of the other so the rebound will be the same.
Or am I missing something?

Yep if it hits the corner exactly, it would always bounce in the opposite direction both horizontally and vertically.

I had this problem with a 3D breakout game I coded. I think you just have to consider all collisions (both walls) rather than just the first one or most prominent one.

But no ball TRUELY hits a corner, it would always hit one edge first if you looked at it down to the microscopic level. It only hits in code due to time not being infinitely sliced by the game. But yeah I agree, if in my code I test for both I can make it reverse along both directions. I suppose in reality with a soft ball or corner that's when you get a "random" exit angle.

You're really talking utter balls recently aren't you.

So the final angle of the ball merely depends on which line I test first for collision
Calculate the collision normal by taking the angle from the point of collision to the center of the ball, and not from the lines surface normal. That way it doesn't matter which of the two lines you test, you'll always get the correct collision normal. To add a little to this, the point of collision will be the point on the line that is closest to the balls center. There are a couple of functions in the code archive for calculating this.

In your third picture the ball should return along the path it came. The angle should be the average of the two walls it joins, essentially it should be a very thin wall like this:
|
|
\ _ _

You're really talking utter balls recently aren't you.
sure am, and proud of it too :-) plus I've been enjoying drawing balls in all sorts of funny positions - bouncing around here and there, going in holes and skirting round hole rims, and even getting stuck on point bits (arg).

Oddball: I'm just going to think about that.

markcw: might seem logical but I don't think it's realistic. Wonder what would happen with a marble dropped on the edge of a steel triangle. Bet it wouldn't bounce back up. It would go left or right depending on where it hit first because it would've always been a fraction of a mm to one side or the other the point.

I think you're losing yourself here. Just randomize the reaction on a corner, I think you'll get pretty much the same realistic results! There is no way a player could claim that it came off the corner completely wrong, and I assume if it is a corner then it's not the player's objective to hit it. Either way he should be punished, and jolly-well severely too I say...corners indeed.

Only a bowling ball would give a true rebound from the wall, a football would squish around the corner and probably bounce back towards you, although the angle would be adjusted slightly depending upon whether there was more ball over the left side of the corner or the right side.

I'd make it rebound backwards but add a little bit of random left or right to it (assuming you're making a football game). You could make it accurate by taking the position of the corner, transform it into the local space of the ball, then work out whether it's left or right of the ball's centre, then adjust the rebound angle accordingly.

Yeah I'm not overly worried about this is was more a sorta coding physics "philosophy" question :-)

It bursts!

Seriously, i would try adding a kind of chaos system that mabe sticks in some kind of randomness to the deflection.
You could add a bias to the randomness by using the center of the ball in relation to the vertex on the corner.

Other than that, no idea :/

It depends on the elaticity of the ball and the corner. When playing Billiards, you can hit the corner of a pocket and have the ball bounce straight back along the line it came. It is quite easy to do.

If both items have no elasticity, ie. glass marble, steel triangle, it is still minutely possible that it will hit in the exact right spot to make it rebound straight back.

Then there is always the possibility that the corner is so sharp, that the ball gets impaled and is stuck. ;)

I guess if you want it to be really acurate then the corner is never really a pointed corner. Its a very tiny tiny rounded corner..
So you can have the two lines not quite touch and place a tiny little ball in the corner to join them.
Then when your ball collides it will either hit a line or the ball.

I say the reason why your ball technically won't react properly is because you are thinkign of your ball as a single object - a pefect sphere, rather than the impression of a sphere created from lots of small particles or atoms, which would individually collide with the corner and some deformation would take place etc.

yes I see.

I'm not certain if you will be able to use this, but, it may help.

Const	ORB_MAX = 4

;Collision
Const	COLLISIONMETHOD_ELLIPSOID	=	1
Const	COLLISIONMETHOD_POLYGON	=	2
Const	COLLISIONMETHOD_BOX	=	3
Const	COLLISIONRESPONSE_STOP	=	1
Const	COLLISIONRESPONSE_SLIDE	=	2
Const	COLLISIONRESPONSE_SLIDENOSLOPE	=	3

Const	COLLISIONTYPE_NONE	=	0
Const	COLLISIONTYPE_ROOM	=	1
Const	COLLISIONTYPE_ORB	=	2

Type Orb
	;Purpose: Orb object
	;Properties:
	Field ID
	Field entity%;
	Field velx#; velocity vector used in Phsysics
	Field vely#;
	Field velz#;
	Field radius#;
End Type

Global Orb_ID.Orb[ORB_MAX]
Global Orbs

Function  OrbNew.Orb()
	;Purpose: Creates HP_Orb Instance; Sets Default Property Values
	;Parameters: TBD
	;Return: HP_Orb Instance		
	this.Orb = New Orb
	Orbs = Orbs + 1
	this\ID = Orbs
	Orb_ID[this\ID] = this
	this\entity% = CreateSphere(32)
	EntityShininess(this\entity%,.7)
	EntityColor(this\entity,255,0,0)
	NameEntity(this\entity%,this\ID)
	this\radius = .5
	ScaleEntity(this\entity%,this\radius#,this\radius#,this\radius#)
	EntityRadius(this\entity%,this\radius#)
	EntityType(this\entity%,COLLISIONTYPE_ORB)
	Return this 
End Function

;create a big cube for ROOMs here 

Function OrbUpdate()
	;Purpose: Main Loop Update. Updates all HP_Orb Instances.
	;Parameters: None
	;Return: None
	For this.Orb = Each Orb
		
		;Orb Physics, Special Thanks to Stevie G & DarkEagle 
		
		;gradually slow down
		;this\velx=this\velx*0.99
		;this\vely=this\vely*0.99
		;this\velz=this\velz*0.99		
		
		For OrbCountCollisions = 1 To CountCollisions(this\entity)
			; Calculate Bounce	
			
			;Get position of the surface collided with.
			OrbPhysicsX# = CollisionX#(this\entity, OrbCountCollisions) 
			OrbPhysicsY# = CollisionY#(this\entity, OrbCountCollisions) 
			OrbPhysicsZ# = CollisionZ#(this\entity, OrbCountCollisions) 
			
			; Get the normal of the surface collided with. 
			OrbPhysicsNx# = CollisionNX#(this\entity, OrbCountCollisions) 
			OrbPhysicsNy# = CollisionNY#(this\entity, OrbCountCollisions) 
			OrbPhysicsNz# = CollisionNZ#(this\entity, OrbCountCollisions) 
			
			;move it slightly away from collision
			TranslateEntity(this\entity, .01 * OrbPhysicsNx , .01 * OrbPhysicsNy , .01 * OrbPhysicsNz)
							
			; Compute the dot product of the ball's motion vector and the normal of the surface collided with. 
			OrbPhysicsVdotN# = this\velx#*OrbPhysicsNx# + this\vely#*OrbPhysicsNy# + this\velz#*OrbPhysicsNz# 
	
			;set coeficient of restitution
			OrbPhysicsCOR# = .987654321 	
			;OrbPhysicsCOR# = 0.0	;inelastic collision
			;OrbPhysicsCOR# = 1.0 ;elastic collision
			
			; Calculate the normal force. 
			OrbPhysicsNFx# = -( 1.0 + OrbPhysicsCOR ) * OrbPhysicsNx# * OrbPhysicsVdotN# 
			OrbPhysicsNFy# = -( 1.0 + OrbPhysicsCOR ) * OrbPhysicsNy# * OrbPhysicsVdotN# 
			OrbPhysicsNFz# = -( 1.0 + OrbPhysicsCOR ) * OrbPhysicsNz# * OrbPhysicsVdotN# 
			
			this\velx# = this\velx# + OrbPhysicsNFx#
			this\vely# = this\vely# + OrbPhysicsNFy#
			this\velz# = this\velz# + OrbPhysicsNFz#
					
			;Get Entity Type of the surface collided with. 	
			OrbCollisionEntity = CollisionEntity(this\entity,OrbCountCollisions)
			Select GetEntityType (OrbCollisionEntity)
			
				Case COLLISIONTYPE_ROOM
					;do stuff to Orb or ROOM entity here
										
				Case COLLISIONTYPE_ORB
					Orb2.Orb=Orb_ID[EntityName(OrbCollisionEntity)]
					;inverts the velocity vector						
					Orb2\velx=-this\velx
					Orb2\vely=-this\vely
					Orb2\velz=-this\velz
						
			End Select			
			
		Next

		TranslateEntity(this\entity, this\velx, this\vely, this\velz)

	Next
End Function	

;==============
;MAIN
;==============

.MAIN_START
	;setup 3D before calling the next commands
	Graphics3D(800,600,32,2)
	SetBuffer(BackBuffer())
	
	Collisions(COLLISIONTYPE_ORB,COLLISIONTYPE_ORB,COLLISIONMETHOD_ELLIPSOID,COLLISIONRESPONSE_SLIDE)
	Collisions(COLLISIONTYPE_ORB,COLLISIONTYPE_ROOM,COLLISIONMETHOD_POLYGON,COLLISIONRESPONSE_SLIDE)
	
	;setup camera and lights here
	Camera=CreateCamera()
	PositionEntity(Camera,0,0,-20) 
	CameraLight=CreateLight()
	RotateEntity(CameraLight,90,0,0)
	
	;setup big cube as a room
	Room = CreateCube()
	ScaleEntity(Room,10,10,10)
	FlipMesh(Room)
	EntityType(Room,COLLISIONTYPE_ROOM)
	
	;setup some orbs	
	Dim Orb.Orb(ORB_MAX)
	
	For loop = 1 To ORB_MAX
		;create some Orbs using the OrbNew() function
		Orb(loop) = OrbNew()
	
		;set Rnd velocity vector for Orbs 
		Orb(loop)\velx = Rnd(-1,1)
		Orb(loop)\vely = Rnd(-1,1)
		Orb(loop)\velz = Rnd(-1,1)
	Next


.MAIN_UPDATE
	Repeat
	
		OrbUpdate()
		
		UpdateWorld() 
		RenderWorld()
		
		Flip()
		
	Until KeyHit(1)


.MAIN_STOP

	End


Looks interesting but unfortunately I don't have B3D. I bet other people will find it useful though, thanks!