/* start out with the boat stopped, and over time, iterate accelerating boat until it reaches steady state. The speed of the boat is known already from apparent wind, this function finds it for true wind */ void BoatPlan::BoatSteadyState(double W, double VW, double &B, double &VB, double &A, double &VA, Boat &boat) { /* starting out not moving */ VB = 0, A = W, VA = VW; double lp = .1; const int count = 128; double bucket = 0; int bcount = 0; for(;;) { double v = VelocityBoat(A, VA); if(v == 0) { // we cannot sail this way B = 0; VB = 0; return; } double a = v - VB; double drag = boat.FrictionDrag(VB) + boat.WakeDrag(VB); if(isnan(drag)) { VB = 0; return; } a -= drag; if(bcount == count) { VB = bucket / count; a = 0; } if(fabs(a) < 1e-2 || lp < 1e-2) { if(VB < 0) // not allowing backwards sailing VB = 0; B = AngleofAttackBoat(A, VA); return; /* reached steady state */ } if(a < 0) { bucket += VB; bcount++; // lp *= .97; } VB = (1-lp)*VB + lp*(VB+a); /* lowpass to get a smooth update */ VA = VelocityApparentWind(VB, W, VW); A = DirectionApparentWind(VA, VB, W, VW); } }
/* start out with the boat stopped, and over time, iterate accelerating boat until it reaches steady state. The speed of the boat is known already from apparent wind, this function finds it for true wind */ void BoatPlan::BoatSteadyState(double W, double VW, double &B, double &VB, double &A, double &VA, Boat &boat) { /* starting out not moving */ VB = 0, A = W, VA = VW; double lp = .03; for(;;) { double v = VelocityBoat(A, VA); double a = v - VB; double drag = boat.FrictionDrag(VB) + boat.WakeDrag(VB); a -= drag; if(fabs(a) < 1e-2 || a < 0) { B = AngleofAttackBoat(A, VA); return; /* reached steady state */ } VB = (1-lp)*VB + lp*(VB+a); /* lowpass to get a smooth update */ VA = VelocityApparentWind(VB, W, VW); A = DirectionApparentWind(VA, VB, W, VW); } }