double TauMCMissile::get_aim(SpaceObject *tgt) { STACKTRACE; Vector2 tv = tgt->get_vel(); //double tvy = tgt->get_vy(); //double rx = min_delta(tgt->normal_x(), normal_x(), X_MAX); //double ry = min_delta(tgt->normal_y(), normal_y(), Y_MAX); Vector2 r = min_delta(tgt->normal_pos(), normal_pos()); //rx*rx + ry*ry; double r2 = magnitude_sqr(r); double u2 = v * v; //(tvx*tvx + tvy*tvy); double d2v = u2 - magnitude_sqr(tv); double t = r.dot(tv); //(rx*tvx + ry*tvy); double q, p; if (fabs(d2v/u2) > 0.01 ) { q = t*t + r2*d2v; if (q > 0) q = sqrt(q); else return (1e10); p = (t+q)/d2v; q = (t-q)/d2v; if (p > 0) t = p; else t = q; if (t < 0) return (1e10); } else { if (fabs(t)<1e-6) return (1e10); else t = - 0.5 * r2 / t; if (t < 0) return (1e10); } t = normalize(atan3(tv.y*t + r.y, tv.x*t + r.x) - angle, PI2); if (t > PI) t -= PI2; return (t); }
// This method assumes the limits have already been checked. // This method assumes the start and end radius match. // This method assumes arcs are not >180 degrees (PI radians) // cx/cy - center of circle // x/y - end position // dir - ARC_CW or ARC_CCW to control direction of arc static void arc(float cx,float cy,float x,float y,float dir) { // get radius float dx = px - cx; float dy = py - cy; float radius=sqrt(dx*dx+dy*dy); // find angle of arc (sweep) float angle1=atan3(dy,dx); float angle2=atan3(y-cy,x-cx); float theta=angle2-angle1; if(dir>0 && theta<0) angle2+=2*PI; else if(dir<0 && theta>0) angle1+=2*PI; theta=angle2-angle1; // get length of arc // float circ=PI*2.0*radius; // float len=theta*circ/(PI*2.0); // simplifies to float len = abs(theta) * radius; int i, segments = ceil( len * MM_PER_SEGMENT ); float nx, ny, angle3, scale; for(i=0;i<segments;++i) { // interpolate around the arc scale = ((float)i)/((float)segments); angle3 = ( theta * scale ) + angle1; nx = cx + cos(angle3) * radius; ny = cy + sin(angle3) * radius; // send it to the planner line(nx,ny); } line(x,y); }
Type bearing(Type x0, Type y0, Type x1, Type y1, bool nautical = true){ vector<Type> dx(2); if(nautical){ dx(0) = x1-x0; dx(1) = y1-y0; }else{ dx = ll2n(x1,y1) - ll2n(x0,y0); } return atan3(dx(1),dx(0)); }
double VelronCruiser::get_aim(SpaceObject *tgt, double min_angle, double max_angle) { STACKTRACE; if (tgt == NULL) return (-1000); Vector2 tv = tgt->get_vel() - specialRelativity * vel; double tvx = tv.x; double tvy = tv.y; tv = min_delta(tgt->normal_pos(), pos); double rx = tv.x; double ry = tv.y; double r2 = rx*rx + ry*ry; double u2 = specialVelocity; u2 *= u2; double d2v = u2 - (tvx*tvx + tvy*tvy); double t = (rx*tvx + ry*tvy); double q, p; if (fabs(d2v/u2) > 0.01 ) { q = t*t + r2*d2v; if (q > 0) q = sqrt(q); else return (-1000); p = (t+q)/d2v; q = (t-q)/d2v; if (p > 0) t = p; else t = q; if (t < 0) return (-1000); } else { if (fabs(t)<1e-6) return (-1000); else t = - 0.5 * r2 / t; if (t < 0) return (-1000); } if (t * specialVelocity > specialRange) return(-1000); t = normalize((atan3(tvy*t + ry, tvx*t + rx)) - angle, PI2); double d_a = normalize(t - min_angle, PI2); if (d_a > PI) d_a -= PI2; if (d_a > 0) { d_a = normalize(t - max_angle, PI2); if (d_a > PI) d_a -= PI2; if (d_a < 0) return (t); } return (-1000); }