// Copyright (C) 2011 Valeriano Alfonso Rodriguez (Kableado) #include #include "Util.h" ///////////////////////////// // SolveQuadratic // // Solves a Quadratic equation using a, b and c coeficients. int SolveQuadratic(float a,float b,float c,float *Rmin,float *Rmax){ float root; float divisor; float b2; b2=b*b; root=b2-4.0*a*c; if(root<0){ // Complex return(0); } divisor=(2.0*a); if(fabs(divisor)==0.0f){ // +inf -inf return(0); } root=sqrtf(root); Rmin[0]=(float)((-b-root)/divisor); Rmax[0]=(float)((-b+root)/divisor); return(1); } ///////////////////////////// // Intersec_RayUnitCircle // // Intersection between a ray and a Unit Circle. int Intersec_RayUnitCircle(vec2 orig,vec2 vel,vec2 center,float *t){ float a,b,c; float Rmin,Rmax; vec2 distv; float qlvel; float qdistv; // Check if the collision is even posible qlvel=vec2_dot(vel,vel); if(fabs(qlvel)<=0.0f) return(0); vec2_minus(distv,orig,center); qdistv=vec2_dot(distv,distv); // Solve as a unit circle a=qlvel; b=2.0f*vec2_dot(distv,vel); c=qdistv-1.0f; if(SolveQuadratic(a,b,c,&Rmin,&Rmax)){ if(Rmin>=-0.0f && Rmin=-0.0f && Rmin>Rmax && Rmax<=1.0f){ *t=Rmax; return(1); } } return(0); } ///////////////////////////// // Colision_CircleCircle // // Colision point of a circle against another circle. int Colision_CircleCircle( vec2 cir1,float rad1,vec2 vel, vec2 cir2,float rad2, float *t,vec2 n) { vec2 vel_a,orig_a,cen_a,temp; float rads,invrads; float maxx,minx; float maxy,miny; // Check if the collision is even posible rads=rad1+rad2; minx=cir1[0]-rads; maxx=cir1[0]+rads; if(vel[0]>0){ maxx+=vel[0]; }else{ minx+=vel[0]; } if(cir2[0]maxx) return(0); miny=cir1[1]-rads; maxy=cir1[1]+rads; if(vel[1]>0){ maxy+=vel[1]; }else{ miny+=vel[1]; } if(cir2[1]maxy) return(0); // Convert to a unit circle vs ray rads=rad1+rad2; invrads=1.0f/rads; vec2_scale(vel_a,vel,invrads); vec2_scale(orig_a,cir1,invrads); vec2_scale(cen_a,cir2,invrads); if(Intersec_RayUnitCircle(orig_a,vel_a,cen_a,t)){ // Calculate n vec2_scale(temp,vel,*t); vec2_plus(temp,cir1,temp); vec2_minus(temp,cir2,temp); vec2_scale(n,temp,1.0f/rads); return(1); } return(0); }