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

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

Creates a twist foot 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.

begin the DO loop for optimising the seam position to fit cloth width

we are above peak, stop this is last panel ///

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

Now we develop the current panel

Now we compute and store the deviation of top edge of developed panel and straighten this top edge Except if this is the top panel

Now we add the seam and hems allowance

Now we check the width of developed panel

loop on DO as long as the excess of width is positive AND counter <9

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

check if peak has been reached to break off

loop FOR next seam

copying the sails for display ****

copying the developed sail

preparing the displays version of the developed sail

Definition at line 563 of file sailworker.cpp.

References CSailDef::clothW, 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().

{
    /*  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;
    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

    unsigned int j=0, k=0, cnt=0;
    bool flag=false;

    /* 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 vector perpendicular to the leech vector (peak-clew)*/
    CVector3d seamV = CMatrix::rot3d(2,PI/2) * leechV.unit();
    CSubSpace seamSP;
    CVector3d seamVT; // seam twisted
    CSubSpace seamSPT;

    /* 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 exb=0, exc=0, ymax=0;
    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] = 2;
    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++)
    {
        exb=0;
        exc =0;
        cnt =0;

        do
        { /** begin the DO loop for optimising the seam position to fit cloth width */
            cnt++;
            p2[npanel] = p2[npanel-1] + (clothW-seamW-exb)/leechL * leechV;
            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 this is last panel ///
                flag=true;
                p2[npanel] = peak;

                // check where previous point p1 is
                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 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 nominal 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::Layout1 : twist intersection of seam and luff is not a point!");

                if (CVector3d(i- (seamW + clothW/5)*luffV.unit() -p1[npanel-1])*luffV <= 0.00001)
                { // seam intersects below previous panel luff point + 1/5 clothW
                    p1[npanel] = p1[npanel-1]+ (seamW + clothW/5)*luffV.unit();
                    t1[npanel] =2;  // 2=luff type of intersection
                    seamVT = (p1[npanel]-p2[npanel]).unit();
                    seamSPT = CSubSpace(p2[npanel], seamVT.matrix(), GEOCPP_FROM_BASE);
                    i = seamSPT.intersect(luff).getp();
                }
                else if (CVector3d(i-head)*luffV > 0)
                { // seam intersects gaff
                    p1[npanel] = seamSP.intersect(gaff).getp();
                    t1[npanel] = 3;  // 3=gaff type of intersection
                    seamVT = seamV;

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

                /** We now add the intermediate points on all sides of the panel */
                /* Below is the code for the left side depending
                 *  on t1 for the top side and bottom side
                 */
                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], seamVT);
                }
                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] ==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 twist cut 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 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 this 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 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, hemsW);
            else if(flag == true)
                dev.panel[npanel-1].addHems(hemsW, hemsW, leechHemW, 0);
            else
                dev.panel[npanel-1].addHems(hemsW, seamW, leechHemW, 0);

            /** Now we check the width of developed panel */
            ymax = dev.panel[npanel-1].height();
            exc = ymax-clothW;

            exb=exb +.8*exc +1;

            //printf ("P %d count %d exc %f exb %f \n", npanel,cnt,exc,exb);
        }
        /** loop on DO as long as
         *  the excess of width is positive AND counter <9
         */
        while ( exc > 0 && cnt<9);
        /////////////////////////////////////////
        //printf ("P -- %d --- maxW %f\n",cnt, (ymax-ymin));

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

        /** Now we reposition the developed panel such that
         *  bottom minimum is Y=0 AND most 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-1)
        throw CException("CSailDef::Layout1 : got to MAX_PANELS without reaching head, do increase cloth width ");

    /** copying the sails for display **** */
    CSail sail(npanel);
    for( j = 0; j < npanel; j ++)
        sail.panel[j] = lay.panel[j];

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

    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 = top;
        v.x() -= bot.x();
        v.y() += 2*seamW +20; // adding offset to separate panels vertically

        dispsail.panel[j] = dispsail.panel[j] + v;
    }

    return sail;
} ///////////// end layout1 = twist foot ////////////////////////////////


Generated by  Doxygen 1.6.0   Back to index