Exemplo n.º 1
0
/* 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);
    }
}
Exemplo n.º 2
0
Boat* Boat ::boatWithFile(const char *spName)
{
    Boat  *pobSprite = new Boat ();
 
    if (pobSprite && pobSprite->initWithFile(spName))//±¸×¢1
    {
        pobSprite->myInit();
        pobSprite->autorelease();
        return pobSprite;
    }
    CC_SAFE_DELETE(pobSprite);
    return NULL;
} 
Exemplo n.º 3
0
/* 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);
    }
}
Exemplo n.º 4
0
/* eta is a measure of efficiency of the boat, from .01 for racing boats to .5 for
   heavy cruisers */
void BoatPlan::ComputeBoatSpeeds(Boat &boat, PolarMethod method, int speed)
{
//    fileFileName = _T("");
    if(/*polarmethod == FROM_FILE ||*/
       wind_speeds.size() != num_computed_wind_speeds ||
       degree_steps.size() != computed_degree_count) {
        wind_speeds.clear();
        degree_steps.clear();

        for(unsigned int Wi = 0; Wi < computed_degree_count; Wi++)
            degree_steps.push_back(computed_degree_step*Wi);
        UpdateDegreeStepLookup();

        for(unsigned int VWi = 0; VWi < num_computed_wind_speeds; VWi++) {
            wind_speeds.push_back(SailingWindSpeed(computed_wind_speeds[VWi]));

            wind_speeds[VWi].speeds.clear();
            for(unsigned int Wi = 0; Wi < computed_degree_count; Wi++)
                wind_speeds[VWi].speeds.push_back(SailingWindSpeed::SailingSpeed(0, degree_steps[Wi]));
        }
    }

    // for IMF computation
    double SADR = boat.SailAreaDisplacementRatio();
    double lwl_ft = boat.lwl_ft;
    double hull_speed = boat.HullSpeed();

    int VW1i, VW2i;
    if(speed == -1) // all speeds
        VW1i = 0, VW2i = wind_speeds.size() - 1;
    else
        ClosestVWi(speed, VW1i, VW2i);

    for(int VWi = VW1i; VWi <= VW2i; VWi++) {
        for(unsigned int Wi = 0; Wi <= computed_degree_count/2; Wi++) {
            double VW = wind_speeds[VWi].VW;
            double W = Wi * computed_degree_step;

            double B, VB, A, VA;
            switch(method) {
            case TRANSFORM:
                BoatSteadyState(deg2rad(W), VW, B, VB, A, VA, boat);
                break;
            case IMF:
            {
                if(fabsf(W) < 30)
                    VB = 0;
                else {
                    double base_speed  = 2.62 + .066*SADR + .051*lwl_ft;
                    double b = 1 / sqrt(VW + 3);
                    VB = base_speed*(sin(deg2rad(W)/2) + b*cos(deg2rad(W))) * sqrt(20*VW) / 8;
                    if(VB > hull_speed)
                        VB = hull_speed;
                }
            }
            default:
                printf("BoatPlan::ComputeBoatSpeeds called with invalid method: %d\n", method);
                return;
            }

            Set(Wi, VWi, VB, W);
            if(W != 0) // assume symmetric performance
                Set(computed_degree_count-Wi, VWi, VB, DEGREES-W);
        }

        CalculateVMG(VWi);
    }

    polarmethod = method;
}