i'm working on a simple 2d physics (balls and lines) atm in c#, but if all works fine i transfer it to sc2 so everyone can use it. but i have a big problem.
the collision detection between 2 balls
my problem:
first i used
move -> for (int j = 1; j <= MaxBalls; j+=1) -> if (dist <= rad1+rad2) move balls outside them and get new vx and vy
that sucks because they can skip a collision if they have high speed.
then i found a formula to get the Time Of Impact (like Box2D)
i implemented it in my sys and it worked fine for a while (as long as they had high speed) but then they hit with lower speed and they got stuck in each other
so my question is:
does anyone knows another solution for it or can someone help me to fix the bug?
formula for Time Of Impact:
doubleR=Balls[i].Radius+Balls[j].Radius;doublea=Balls[i].Vel.X*Balls[i].Vel.X;doubleb=-2*Balls[j].Pos.X*Balls[i].Vel.X+2*Balls[i].Pos.X*Balls[i].Vel.X;doublec=-2*Balls[i].Pos.X*Balls[j].Pos.X+Balls[i].Pos.X*Balls[i].Pos.X+Balls[j].Pos.X*Balls[j].Pos.X;doubled=Balls[i].Vel.Y*Balls[i].Vel.Y;doublee=-2*Balls[j].Pos.Y*Balls[i].Vel.Y+2*Balls[i].Pos.Y*Balls[i].Vel.Y;doublef=-2*Balls[i].Pos.Y*Balls[j].Pos.Y+Balls[i].Pos.Y*Balls[i].Pos.Y+Balls[j].Pos.Y*Balls[j].Pos.Y;doubleg=a+d;doubleh=b+e;doublek=c+f-R*R;//solve the quadratic equationdoublesqRoot=System.Math.Sqrt(h*h-4*g*k);doublet1=(-h+sqRoot)/(2*g);doublet2=(-h-sqRoot)/(2*g);if(t1>=0&&t1<=1){whatTime=t1;ballsCollided=true;}if(t2>=0&&t2<=1){if(whatTime==null||t2<t1){whatTime=t2;ballsCollided=true;}}if(ballsCollided){/* run collision between ball i and ball j */}
double == fixed in sc2
and the example: (needs windows and min netframe 3.5)
use left mouse to push them away and right to drag
A possible solution would to create a simple traceline between the balls current position and where it would go next and check each point to see if there will be a collision or not. This should work even at high speeds.
You really should consider better names for your variables to make the code easier to read (or add comments). I will look at a working solution a little later today and come back to you.
I'm not familiar with C#, so I don't know how System.Math.Sqrt handles imaginary roots. However the problem I see, unless you deal with it elsewhere, is that your code doesn't check for imaginary roots, which would be the case for all balls that never collide.
i'm working on a simple 2d physics (balls and lines) atm in c#, but if all works fine i transfer it to sc2 so everyone can use it. but i have a big problem.
the collision detection between 2 balls
my problem:
first i used
move -> for (int j = 1; j <= MaxBalls; j+=1) -> if (dist <= rad1+rad2) move balls outside them and get new vx and vy
that sucks because they can skip a collision if they have high speed.
then i found a formula to get the Time Of Impact (like Box2D)
i implemented it in my sys and it worked fine for a while (as long as they had high speed) but then they hit with lower speed and they got stuck in each other
so my question is:
does anyone knows another solution for it or can someone help me to fix the bug?
formula for Time Of Impact:
double == fixed in sc2
and the example: (needs windows and min netframe 3.5)
use left mouse to push them away and right to drag
@HellGateSc2: Go
A possible solution would to create a simple traceline between the balls current position and where it would go next and check each point to see if there will be a collision or not. This should work even at high speeds.
the problem is the required time...
lets say we have 10 balls
10*10*(int)(speed/20)
and this / 0.03 sec? :/
@HellGateSc2: Go
You could calculate the time it takes for it to impact then calculate the distance it will have travelled by the next time tick.
thats what i do
get the time of impact then move with speed * time till impact
but it bugs
@HellGateSc2: Go
You really should consider better names for your variables to make the code easier to read (or add comments). I will look at a working solution a little later today and come back to you.
ok thanks :)
(will update the code a bit to make it better to understand)
@HellGateSc2: Go
I'm not familiar with C#, so I don't know how System.Math.Sqrt handles imaginary roots. However the problem I see, unless you deal with it elsewhere, is that your code doesn't check for imaginary roots, which would be the case for all balls that never collide.
@GalacticBean: Go
If it is anything like C than sqrt does not except imaginary roots. If (h * h - 4 * g * k) becomes negative a domain error will occur.
@Twinmold20: Go
Yeah, that'd make sense. Don't see anything else that could bug it atm.
@Twinmold20: Go
there are no errors but it calculates the time sometimes wrong (i think) :/
@HellGateSc2: Go
Which sort of timer are you going after and how often does it tick?
atm this (because timers makes it buging)
while (true)
{
ball collision
wall collision
System.Threading.Thread.Sleep((int)(FPS * 1000)); /*0.03*1000 = time in ms*/
}
@HellGateSc2: Go
What is the value for FPS?
const double FPS = 0.03;
(first i had 30 as FPS but then i changed it to 0.03 because i don't want to do always 1/FPS)
it says you posted something but i can't find it :o