Logo Search packages:      
Sourcecode: sailcut version File versions  Download package

CSail CSailWorker::LayoutWing ( CSail flatsail,
CSail dispsail 
) [protected]

Creates a WING horizontal cut sail.

Parameters:
flatsail the CSail object that will hold the developed sail
dispsail the CSail object that will hold the display version of the developed sail
Returns:
CSail
Author:
Robert Lainé

This loop FOR will position the seams and determine the number of panels.

We now add the intermediate points on all sides of the normal panel

Now we add the seam and hems allowance

Now we reposition the developed panel such that bottom minimum is Y=0 AND left is X=0

check if peak has been reached to break off

loop FOR next seam

creating the symetrical panels

copying the sails for display

copying the developed sail

preparing the displays version of the developed sail

Definition at line 1136 of file sailworker.cpp.

References CSailDef::clothW, CSailDef::dihedralDeg, FootIntersect(), GaffIntersect(), CSubSpace::getdim(), CSubSpace::getp(), CSubSpace::intersect(), LeechIntersect(), LuffIntersect(), CVector::matrix(), CSail::panel, CMatrix::rot3d(), CSailDef::seamW, CVector::unit(), CVector3d::x(), CVector3d::y(), and Zpoint().

Referenced by makeSail().

{
    // QString txt;
    // txt = "input pt -------------   x=" + QString::number (pt1.x() ) + "  y=" + QString::number (pt1.y() ) + "  z="+ QString::number (pt1.z() );
    // qDebug ( txt );

    /*  First create arrays p1 and p2 of points at the end of each seams
    *   located on the straight edge of the sail (no round)
    */
    CPoint3d p1[MAX_PANELS], p2[MAX_PANELS];

    /* Create two temporary sails lay and the corresponding dev */
    CSail lay(MAX_PANELS); // 3D sail
    CSail dev(MAX_PANELS); // developed sail

    /* create number of panels */
    unsigned int npanel=1, np=1;
    unsigned int npl= lay.panel[0].right.nbpoints();   // number of right/left points
    unsigned int npb= lay.panel[0].bottom.nbpoints(); // number of bottom/top points

    /* angle of the half wing from X-Y plane */
    real alfa = (180 - dihedralDeg) *PI/360;

    unsigned int j=0, k=0;
    bool flag=false;  // to check if top of sail is reached

    /* create arrays t1 and t2 of type of intersection
    *  respectively at points p1 on luff side and p2 on leech side
    *  t=1 seam intersect foot at point p1
    *  t=2 seam intersect luff
    *  t=3 seam intersect gaff
    *  t=4 seam intersect leech
    */
    int t1[MAX_PANELS], t2[MAX_PANELS];

    /* define point i for intersections */
    CPoint3d i;

    /* define seamV as the horizontal vector*/
    CVector3d seamV = CVector3d (-1,0,0);
    CSubSpace seamSP;

    /* create variables for the development and edge corrections */
    CPoint3d top = CPoint3d (0,0,0);
    CPoint3d bot = CPoint3d (0,0,0);
    CVector3d v  = CVector3d (0,0,0);
    CVector3d vb = CVector3d (0,0,0);
    CVector3d vk = CVector3d (0,0,0);

    /* create variable for edge correction */
    CVector3d deviation [30];
    CVector3d deviaPrev [30];
    for (k=0; k<29; k++)
    {
        deviation[k] = CVector3d (0,0,0); // set all deviations to zero
        deviaPrev[k] = deviation [k];
    }

    /* create variable to monitor excess over cloth width */
    real CC=0, x=0, y=0;

    /* seam 0 is on the foot of the sail ending at the clew */
    p1[0] = tack; // initialised at tack point
    p2[0] = clew;
    t1[0] = 1;
    t2[0] = 4;    // type=4=leech intersection

    /** This loop FOR will position the seams and determine the number of panels. */
    for (npanel = 1; npanel < MAX_PANELS-1; npanel++)
    {
            p2[npanel] = p2[npanel-1] + (clothW-seamW)/(seamV*leechVP) * leechV.unit();
            t2[npanel] = 4; // type2=4=leech intersection for all horizontally cut panels
            seamSP = CSubSpace(p2[npanel], seamV.matrix(), GEOCPP_FROM_BASE);

            if (CVector3d(p2[npanel]-peak)*leechV > 0)  // we are above peak, stop last panel
            {
                flag=true;
                p2[npanel] = peak;
                // check on which side of the sail the previous point p1 is located
                if (t1[npanel-1] < 2 )
                { // previous seam on foot
                    p1[npanel] = head;
                    t1[npanel] = 2; // set on luff
                    // left points on foot-tack-luff
                    lay.panel[npanel-1].left.fill(p1[npanel-1], tack, p1[npanel]);
                    for (k=0; k<npl/2; k++)
                        lay.panel[npanel-1].left.point[k]=FootIntersect(lay.panel[npanel-1].left.point[k], seamV);
                    for (k=npl/2+1; k<npl; k++)
                        lay.panel[npanel-1].left.point[k]=LuffIntersect(lay.panel[npanel-1].left.point[k], seamV);
                }
                else if (t1[npanel-1] == 2)
                { // left points on luff
                    p1[npanel] = head;
                    t1[npanel] = 2;
                    lay.panel[npanel-1].left.fill(p1[npanel-1], p1[npanel]);
                    for (k=0; k<npl; k++)
                        lay.panel[npanel-1].left.point[k]=LuffIntersect(lay.panel[npanel-1].left.point[k], seamV);
                }
                else
                { // left points on gaff
                    p1[npanel] = p1[npanel-1];
                    t1[npanel] = 3;
                    lay.panel[npanel-1].left.fill(p1[npanel-1], p1[npanel]);
                    for (k=0; k<npl; k++)
                        lay.panel[npanel-1].left.point[k]=GaffIntersect(lay.panel[npanel-1].left.point[k], seamV);
                }

                // fill right points on leech
                lay.panel[npanel-1].right.fill(p2[npanel-1],p2[npanel]);
                for (k=0; k<npl; k++)
                    lay.panel[npanel-1].right.point[k]=LeechIntersect(lay.panel[npanel-1].right.point[k], seamV);

                // fill bottom points
                lay.panel[npanel-1].bottom.fill(lay.panel[npanel-1].left.point[0], lay.panel[npanel-1].right.point[0]);

                // fill top  points
                lay.panel[npanel-1].top.fill(lay.panel[npanel-1].left.point[npl-1], lay.panel[npanel-1].right.point[npl-1]);

                // move all top points of top panel to gaff curve
                for( k=1; k < npb-1; k++)
                    lay.panel[npanel-1].top.point[k]=GaffIntersect(lay.panel[npanel-1].top.point[k], CVector3d (head.y()-peak.y(),peak.x()-head.x(),0));

                ////// end peak panel /////
            }
            else        // normal panel  ///////////////////////////
            {
                /* find position of luff/seam intersection relative to tack and head */
                i = seamSP.intersect(luff).getp();

                /* the case when the intersection is not a point needs to be handled */
                if (seamSP.intersect(luff).getdim() != 0)
                    throw CException("CSailDef::Layout0 : intersection of seam and luff is not a point!");

                if (CVector3d(i-tack)*luffV < 0)
                {
                    // seam intersects foot
                    p1[npanel] = seamSP.intersect(foot).getp();
                    t1[npanel] =1;  // 1=foot type of intersection

                    if (npanel == 1)
                    { // set lower edge to start at same point p1
                        p1[0] = p1[npanel];
                        t1[0] = 1;
                    }
                    /* the case when the intersection is not a point needs to be handled */
                    if (seamSP.intersect(foot).getdim() != 0)
                        throw CException("CSailDef::Layout0 : intersection of seam and foot is not a point!");
                }
                else if (CVector3d(i-head)*luffV > 0)
                {
                    // seam intersects gaff
                    p1[npanel] = seamSP.intersect(gaff).getp();
                    t1[npanel] = 3;  // 3=gaff type of intersection

                    /* the case when the intersection is not a point needs to be handled */
                    if (seamSP.intersect(gaff).getdim() != 0)
                        throw CException("CSailDef::Layout0 : intersection of seam and foot is not a point!");
                }
                else
                {
                    // seam intersects luff
                    p1[npanel] = i;
                    t1[npanel] = 2;  // luff
                    if (npanel == 1)
                    {
                        // force seam 0 to start at the tack
                        p1[0] = tack;
                        t1[0] = 2;
                    }
                }

                /** We now add the intermediate points on all sides of the normal panel  */

                /* Below is the code for the left side depending
                *  on t1 for the top side and bottom side
                */
                if (t1[npanel-1] == 1 && t1[npanel] == 1)
                {
                    // full foot
                    lay.panel[npanel-1].left.fill(p1[npanel-1], p1[npanel]);
                    for (k=0; k<npl; k++)
                        lay.panel[npanel-1].left.point[k]=FootIntersect(lay.panel[npanel-1].left.point[k], seamV);
                }
                else if (t1[npanel-1] == 2 && t1[npanel] == 2)
                {
                    // full luff
                    lay.panel[npanel-1].left.fill(p1[npanel-1], p1[npanel]);
                    for (k=0; k<npl; k++)
                        lay.panel[npanel-1].left.point[k]=LuffIntersect(lay.panel[npanel-1].left.point[k], seamV);
                }
                else if (t1[npanel-1] == 3 && t1[npanel] == 3)
                {
                    // full gaff
                    lay.panel[npanel-1].left.fill(p1[npanel-1], p1[npanel]);
                    for (k=0; k<npl; k++)
                        lay.panel[npanel-1].left.point[k]=GaffIntersect(lay.panel[npanel-1].left.point[k], seamV);
                }
                else if ((t1[npanel-1] == 1) && (t1[npanel] == 2))
                {
                    // foot-tack-luff
                    lay.panel[npanel-1].left.fill(p1[npanel-1], tack, p1[npanel]);
                    for (k=0; k<npl/2; k++)
                        lay.panel[npanel-1].left.point[k]=FootIntersect(lay.panel[npanel-1].left.point[k], seamV);
                    for (k=npl/2+1; k<npl; k++)
                        lay.panel[npanel-1].left.point[k]=LuffIntersect(lay.panel[npanel-1].left.point[k], seamV);
                }
                else if ((t1[npanel-1] == 2) && (t1[npanel] == 3))
                {
                    // luff-head-gaff
                    lay.panel[npanel-1].left.fill(p1[npanel-1], head, p1[npanel]);
                    for (k=0; k<npl/2; k++)
                        lay.panel[npanel-1].left.point[k]=LuffIntersect(lay.panel[npanel-1].left.point[k], seamV);
                    for (k=npl/2+1; k<npl; k++)
                        lay.panel[npanel-1].left.point[k]=GaffIntersect(lay.panel[npanel-1].left.point[k], seamV);
                } // end IF ELSE for left side

                /* Below is the code for the intermediate points of the right side
                *  which are all on the leech for a crosscut layout.
                */
                lay.panel[npanel-1].right.fill(p2[npanel-1],p2[npanel]);
                for (k=0; k<npl; k++)
                    lay.panel[npanel-1].right.point[k]=LeechIntersect(lay.panel[npanel-1].right.point[k], seamV);

                /* Below is the code for the intermediate points of the top and bottom sides.
                *  The first point is identical to the last point of the left side
                *  The last point is identical to the last point of the right side
                */
                lay.panel[npanel-1].top.fill(lay.panel[npanel-1].left.point[npl-1], lay.panel[npanel-1].right.point[npl-1]);
                lay.panel[npanel-1].bottom.fill(lay.panel[npanel-1].left.point[0], lay.panel[npanel-1].right.point[0]);

                /* Below is the code for the intermediate points of the bottom side of first panel  */
                if (npanel == 1)
                { // move bottom side of first panel to foot curve
                    for( k=1; k < npb-1; k++)
                        lay.panel[0].bottom.point[k] = FootIntersect(lay.panel[0].bottom.point[k], CVector3d(0,-1,0));
                }
            } //// end else normal panel ///////////////////////

            /* Now we go over all the points and calculate their z */
            for( k = 0; k < npl; k ++)
                lay.panel[npanel-1].left.point[k] = Zpoint(lay.panel[npanel-1].left.point[k]);
            for( k = 0; k < npl; k ++)
                lay.panel[npanel-1].right.point[k] = Zpoint(lay.panel[npanel-1].right.point[k]);
            for( k = 0; k < npb; k ++)
                lay.panel[npanel-1].top.point[k] = Zpoint(lay.panel[npanel-1].top.point[k]);
            for( k = 0; k < npb; k ++)
                lay.panel[npanel-1].bottom.point[k] = Zpoint(lay.panel[npanel-1].bottom.point[k]);

            /* Now we rotate the panel by the dihedral angle */
            lay.panel[npanel-1] = lay.panel[npanel-1].rotate(tack , CMatrix::rot3d(0 , alfa) );

            /* and if it is the first panel we cut the foot to tack level */
            if (npanel == 1)
            {
                for( k=0; k < npb-1; k++)
                        lay.panel[0].bottom.point[k].y() = tack.y();
                lay.panel[0].left.point[0].y() = tack.y();
                lay.panel[0].right.point[0].y() = tack.y();
            }

            /* debugging
            if (npanel ==2 && sailType==WING)
            {
                for (k=0; k<4; k++)
                {
                    QString   txt;
                    txt = "Zpoint = " + QString::number (k) + "   x=" + QString::number (lay.panel[npanel-1].left.point[k].x()  ) + "   y="+ QString::number (lay.panel[npanel-1].left.point[k].y() ) +"   z="+ QString::number (lay.panel[npanel-1].left.point[k].z() );
                    qDebug ( txt );
                }
            }
            */

            /* Now we develop the current panel */
            if (npanel == 1)
            {
                dev.panel[npanel-1] = lay.panel[npanel-1].develop(ALIGN_TOP);
            }
            else
            {
                dev.panel[npanel-1] = lay.panel[npanel-1].develop(ALIGN_BOTTOM);
                // add deviation of previous panel top edge to bottom edge
                for( k = 1; k < npb-1; k ++)
                    dev.panel[npanel-1].bottom.point[k] = dev.panel[npanel-1].bottom.point[k] + deviaPrev[k];
            }

            /* Now we compute and store the deviation of top edge of
            *   the developed panel and straighten this top edge
            *   except if this is the top panel
            */
            if (flag == false)
            {
                vb= CMatrix::rot3d(2,PI/2)*CVector3d(dev.panel[npanel-1].top.point[npb-1] -dev.panel[npanel-1].top.point[0]).unit();
                for( k = 1; k < npb-1; k ++)
                {
                    vk= CVector3d (dev.panel[npanel-1].top.point[k] - dev.panel[npanel-1].top.point[0]);
                    v= vb * -(vk*vb);
                    deviation[k] = v;
                    dev.panel[npanel-1].top.point[k] = dev.panel[npanel-1].top.point[k] + deviation[k];
                }
            }

            /** Now we add the seam and hems allowance */
            if (npanel == 1)
                dev.panel[npanel-1].addHems(hemsW, seamW, leechHemW, seamW);
            else if (flag == true)
                dev.panel[npanel-1].addHems(hemsW, hemsW, leechHemW, 0);
            else
                dev.panel[npanel-1].addHems(hemsW, seamW, leechHemW, 0);

        ////////////////////////////////////////////

        for (k=0; k<npb; k++)
            deviaPrev[k] = deviation[k];

        /** Now we reposition the developed panel such that
        *  bottom minimum is Y=0 AND left is X=0
        */
        dev.panel[npanel-1] = dev.panel[npanel-1].reframe(LOW_LEFT);

        /** check if peak has been reached to break off */
        if (flag == true)
            break;
    }/** loop FOR next seam */
    ////////////////////////////////////////

    if (npanel == MAX_PANELS/2 -1)
        throw CException("CSailDef::Layout0 : got to MAX_PANELS without reaching head, do increase cloth width ");

    /** creating the symetrical panels */
    np = npanel;
    for (j = 0; j<np+1; j++)
    {
        npanel ++;
        lay.panel[npanel] = lay.panel[j];
        dev.panel[npanel] = dev.panel[j];

        for (k=0; k<npb; k++)
        {
            lay.panel[npanel].top.point[k].y() = -lay.panel[npanel].top.point[k].y();
            lay.panel[npanel].bottom.point[k].y() = -lay.panel[npanel].bottom.point[k].y();
        }
        for (k=0; k<npl; k++)
        {
            lay.panel[npanel].left.point[k].y() = -lay.panel[npanel].left.point[k].y();
            lay.panel[npanel].right.point[k].y() = -lay.panel[npanel].right.point[k].y();
        }
    }

    /** copying the sails for display */
    CSail sail(2*npanel+1);

    for( j = 0; j < npanel; j ++)
        sail.panel[j] = lay.panel[j];

    /** copying the developed sail */
    flatsail = CSail(2*npanel+1);

    for (j=0 ; j < npanel ; j++)
    {
        flatsail.panel[j] = dev.panel[j];
    }

    /** preparing the displays version of the developed sail */
    dispsail = flatsail;

    for (j=1; j < npanel; j++)
    {
        top = dispsail.panel[j-1].top.point[0];
        bot = dispsail.panel[j].bottom.point[0];

        // rotation to align bottom of panel to top of previous panel
        x = dispsail.panel[j-1].top.point[npb-1].x()-top.x();
        y = dispsail.panel[j-1].top.point[npb-1].y()-top.y();
        CC= atan2(y,x);
        dispsail.panel[j] = dispsail.panel[j].rotate(bot,CMatrix::rot3d(2,CC));

        // translation v to align panel bottom edge origin to previous panel upper edge origin
        v = CVector3d (top - CPoint3d(0,0,0));
        v.x()= v.x()-bot.x();
        v.y() = v.y()+ 2*seamW +20; // adding offset to separate panels vertically

        dispsail.panel[j] = dispsail.panel[j] + v;
    }
    ///
    return sail;
} ///////////// end layoutWing = cross cut or horizontal /////////////////////


Generated by  Doxygen 1.6.0   Back to index