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

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

Creates a radial 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é

Cutting the luff side panels

Cutting the middle panels

cutting the leech side panels

copying 3d lay into 3d sail

Definition at line 1533 of file sailworker.cpp.

References CSailDef::clothW, FootIntersect(), GaffIntersect(), CSubSpace::getp(), CSubSpace::intersect(), LeechIntersect(), LuffIntersect(), CSailDef::nbGores, CSailDef::nbLuffGores, CSailDef::nbSections, CSail::panel, CSailDef::seamW, CVector3d::x(), CVector3d::y(), and Zpoint().

Referenced by makeSail().

{
    unsigned int h=0, j=0, k=0, a=1, b=1;
    unsigned int ngLuff = nbLuffGores;  // limit of luff gores
    unsigned int ng1=0;   // number of central panels
    //bool flag=false;
    real x=0, xm=0, xp=0, ym=0;

    CPoint3d pt0, pt1, pt2, pt3, pt4, ptCentre, ptFoot;  // points

    /* 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 nps[10];   // number of panels per sections

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

    /* 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];
    for (k=0; k<29 ; k++)
        deviation[k] = CVector3d (0,0,0); // set all deviations to zero

    /* Create arrays of points at horizontal seams ends 10 maximum */
    CPoint3d luffH[10];    // point at the luff end of the horizontal seam
    CPoint3d leechH[10];   // point at the leech end of the horizontal seam
    CSubSpace seamH[10];   // corresponding seam lines
    CSubSpace seamSP;  // a seam line

    for ( h=0; h<nbSections; h++)  // one more horizontal line than nbSections
    {
        pt1 = tack + luffV * (real(h) / nbSections );
        pt2 = clew + leechV * (real(h) / nbSections );
        luffH[h] = LuffIntersect( pt1, CVector3d(pt1-pt2) );
        leechH[h] = LeechIntersect( pt2, CVector3d(pt2-pt1) );
        seamH[h] = CSubSpace(luffH[h], CVector3d(leechH[h] - luffH[h]).matrix(), GEOCPP_FROM_BASE);
    }

    h= nbSections;
    luffH[h] = head;
    leechH[h] = peak;
    seamH[h] = gaff;

    /*  Create arrays of points on luff and leech catenaries
    *   Luff and leech catenaries are the lines going from each side
    *     of the middle panel of the gaff to the tack and clew.
    *   They separate the surface of the sail in 3 zones:
    *     the luff zone, the central zone and the leech zone.
    *   The luff and leech zone have the same number of radial
    *     panels from top to bottom while in the central zone
    *     the number of panels increase by one at each section.
    */
    CPoint3d luffCatenary[11], leechCatenary[11];

    // top point on luff catenary
    pt0 = head + gaffV * ( real(ngLuff) / real(nbGores) );
    luffCatenary[nbSections] = pt0;

    // top point on leech catenary
    pt0 = head + gaffV * ( real(ngLuff+1) / real(nbGores) );
    leechCatenary[nbSections] = pt0; // top of leech catenary

    // other points on both catenaries
    for ( h=nbSections-1; h>0; h--)
    {
        pt0 = tack + footV*( real(h) / real(nbSections) )*( real(ngLuff) / real(nbGores) );
        seamSP = CSubSpace(luffCatenary[h+1], CVector3d(pt0 - luffCatenary[h+1]).matrix(),GEOCPP_FROM_BASE);
        luffCatenary[h] = seamH[h].intersect(seamSP).getp();

        pt0 = clew - footV*( real(h) / real(nbSections) )*( real(nbGores-ngLuff) / real(nbGores) );
        seamSP = CSubSpace(leechCatenary[h+1], CVector3d(pt0 - leechCatenary[h+1]).matrix(),GEOCPP_FROM_BASE);
        leechCatenary[h] = seamH[h].intersect(seamSP).getp();
    }

    h=0;
    luffCatenary[h] = tack;
    leechCatenary[h] = clew;

    /* Now we cut the radial panels
    *  panels are oriented with lower edge vertical toward luff
    *  and left side at the top of each section
    */
    npanel = 0;
    ng1 = 0;  // initialise number of central panels

    for (h = nbSections; h>0; h--)
    { // sweeping from top section downward
        nps[h]=0;  // counter of panels in current section
        /** Cutting the luff side panels */
        for (j=1; j<=ngLuff; j++)
        {
            if (j == 1)
            { // place bottom end points on luff catenary
                pt1 = luffH[h];
                pt2 = luffH[h-1];

                lay.panel[npanel].bottom.fill(pt1 , pt2);

                for (k=1; k<npb-1; k++)
                    lay.panel[npanel].bottom.point[k] = LuffIntersect(lay.panel[npanel].bottom.point[k], CVector3d(luffH[h-1]-leechH[h-1]) );
            }
            else
            { // copy previous points
                pt1 = pt3;
                pt2= pt4;
                lay.panel[npanel].bottom.fill(pt1 , pt2);
            }

            // we compute the top end points
            pt3 = luffH[h] + CVector3d(luffCatenary[h]-luffH[h]) * (real(j)/ngLuff);
            if (h == nbSections)
                pt3 = GaffIntersect( pt3, gaffVP );

            pt4 = luffH[h-1] + CVector3d(luffCatenary[h-1]-luffH[h-1]) * (real(j)/ngLuff);

            // we fill the other edges
            lay.panel[npanel].top.fill(pt3, pt4);
            lay.panel[npanel].left.fill(pt1 , pt3);
            lay.panel[npanel].right.fill(pt2 , pt4);

            if (h == nbSections)
            {
                for (k=1; k<npl-1; k++)
                    lay.panel[npanel].left.point[k] = GaffIntersect(lay.panel[npanel].left.point[k], gaffVP );
            }

            // We compute Z
            for( k = 0; k < npl; k ++)
                lay.panel[npanel].left.point[k] = Zpoint(lay.panel[npanel].left.point[k]);
            for( k = 0; k < npl; k ++)
                lay.panel[npanel].right.point[k] = Zpoint(lay.panel[npanel].right.point[k]);
            for( k = 0; k < npb; k ++)
                lay.panel[npanel].top.point[k] = Zpoint(lay.panel[npanel].top.point[k]);
            for( k = 0; k < npb; k ++)
                lay.panel[npanel].bottom.point[k] = Zpoint(lay.panel[npanel].bottom.point[k]);

            // We develop the current panel
            dev.panel[npanel] = lay.panel[npanel].develop(ALIGN_TOP);


            // We add the seams and hems allowance
            if (h == nbSections && j == 1)
                dev.panel[npanel].addHems(hemsW, seamW, 0, hemsW);
            else if (j == 1)
                dev.panel[npanel].addHems(seamW, seamW, 0, hemsW);
            else
                dev.panel[npanel].addHems(seamW, seamW, 0, 0);

            nps[h]++;
            npanel++;
        }

        /** Cutting the middle panels */
        if ( h > 1 )
        {
            ng1++;  // we add one more central panel than section above
            a = int(floor(real(ng1)/2));
            b = int(ceil(real(ng1)/2));

            // we initialise the bottom end points
            pt3 = luffCatenary[h];
            if (h == nbSections)
                pt3 = GaffIntersect( pt3, gaffVP );

            pt4 = luffCatenary[h-1];

            // we now compute the other points
            for (j=1; j<=ng1; j++)
            {
                pt1 = pt3;
                pt2 = pt4;
                pt4 = luffCatenary[h-1] + CVector3d(leechCatenary[h-1]-luffCatenary[h-1])*(real(j)/ng1);

                if (ng1 < 4)
                {
                    pt3 = luffCatenary[h] + CVector3d(leechCatenary[h]-luffCatenary[h])*(real(j)/ng1);
                    if (h == nbSections)
                        pt3 = GaffIntersect( pt3, gaffVP );
                }
                else
                {
                    if (j < a)  // before middle point
                    {
                        pt3 = luffCatenary[h] + CVector3d(leechCatenary[h]-luffCatenary[h])*(real(j)/(ng1-1));
                    }
                    else if (j > b )  // after middle point
                    {
                        pt3 = luffCatenary[h] + CVector3d(leechCatenary[h]-luffCatenary[h])*(real(j-1)/(ng1-1));
                    }
                    else
                    {
                        pt3 = luffCatenary[h] + CVector3d(leechCatenary[h]-luffCatenary[h])*(real(j)/ng1);
                    }
                }

                // we fill the 4 edges
                lay.panel[npanel].left.fill(pt1 , pt3);
                lay.panel[npanel].right.fill(pt2 , pt4);
                lay.panel[npanel].bottom.fill(pt1 , pt2);
                lay.panel[npanel].top.fill(pt3 , pt4);

                if (h == nbSections)
                {
                    for (k=1; k<npl-1; k++)
                        lay.panel[npanel].left.point[k] = GaffIntersect(lay.panel[npanel].left.point[k], gaffVP );
                }

                // we compute Z
                for( k = 0; k < npl; k ++)
                    lay.panel[npanel].left.point[k] = Zpoint(lay.panel[npanel].left.point[k]);
                for( k = 0; k < npl; k ++)
                    lay.panel[npanel].right.point[k] = Zpoint(lay.panel[npanel].right.point[k]);
                for( k = 0; k < npb; k ++)
                    lay.panel[npanel].top.point[k] = Zpoint(lay.panel[npanel].top.point[k]);
                for( k = 0; k < npb; k ++)
                    lay.panel[npanel].bottom.point[k] = Zpoint(lay.panel[npanel].bottom.point[k]);

                // We develop the current panel
                dev.panel[npanel] = lay.panel[npanel].develop(ALIGN_TOP);

                // We add the seams and hems allowance
                if (h == nbSections)
                    dev.panel[npanel].addHems(hemsW, seamW, 0, 0);
                else
                    dev.panel[npanel].addHems(seamW, seamW, 0, 0);

                nps[h]++;
                npanel++;
            }
        }
        else  // middle panels of bottom section h = 1
        {
            // luff side central
            for (j=1; j<=ng1/2; j++)
            {
                pt1 = luffCatenary[h] + CVector3d(leechCatenary[h]-luffCatenary[h])*(real(j-1)/ng1);
                pt2 = tack;

                pt3 = luffCatenary[h] + CVector3d(leechCatenary[h]-luffCatenary[h])*(real(j)/ng1);
                pt4 = pt2;

                ptCentre = pt3; // memorise last point on horizontal seam 1

                lay.panel[npanel].left.fill(pt1 , pt3);
                lay.panel[npanel].right.fill(pt2 , pt4);
                lay.panel[npanel].bottom.fill(pt1 , pt2);
                lay.panel[npanel].top.fill(pt3 , pt4);

                // compute Z
                for( k = 0; k < npl; k ++)
                    lay.panel[npanel].left.point[k] = Zpoint(lay.panel[npanel].left.point[k]);
                for( k = 0; k < npl; k ++)
                    lay.panel[npanel].right.point[k] = Zpoint(lay.panel[npanel].right.point[k]);
                for( k = 0; k < npb; k ++)
                    lay.panel[npanel].top.point[k] = Zpoint(lay.panel[npanel].top.point[k]);
                for( k = 0; k < npb; k ++)
                    lay.panel[npanel].bottom.point[k] = Zpoint(lay.panel[npanel].bottom.point[k]);

                // We develop the current panel
                dev.panel[npanel] = lay.panel[npanel].develop(ALIGN_TOP);

                // We add the seams allowance
                dev.panel[npanel].addHems(seamW, seamW, 0, 0);

                nps[h]++;
                npanel++;
            }

            // luff side lower central
            pt0=(luffCatenary[nbSections]+leechCatenary[nbSections])*0.5;
            ptFoot = FootIntersect( ptCentre , CVector3d(ptCentre-pt0) );
            a = int( (CVector3d(ptFoot-ptCentre).norm()) / (clothW) );
            if (a < 2)
                a = 2;

            for (j=1; j<=a; j++)
            {
                pt1 = ptCentre + CVector3d (ptFoot - ptCentre)*(real(j-1)/a);
                pt2 = tack;
                pt3 = ptCentre + CVector3d (ptFoot - ptCentre)*(real(j)/a);
                pt4 = pt2;

                lay.panel[npanel].left.fill(pt1 , pt3);
                lay.panel[npanel].right.fill(pt2 , pt4);
                lay.panel[npanel].bottom.fill(pt1 , pt2);
                lay.panel[npanel].top.fill(pt3 , pt4);

                // compute Z
                for( k = 0; k < npl; k ++)
                    lay.panel[npanel].left.point[k] = Zpoint(lay.panel[npanel].left.point[k]);
                for( k = 0; k < npl; k ++)
                    lay.panel[npanel].right.point[k] = Zpoint(lay.panel[npanel].right.point[k]);
                for( k = 0; k < npb; k ++)
                {
                    pt0 = lay.panel[npanel].top.point[k];
                    if (j == a)
                        pt0 = FootIntersect(lay.panel[npanel].top.point[k], footVP);
                    lay.panel[npanel].top.point[k] = Zpoint(pt0);
                }
                for( k = 0; k < npb; k ++)
                    lay.panel[npanel].bottom.point[k] = Zpoint(lay.panel[npanel].bottom.point[k]);

                // We develop the current panel
                dev.panel[npanel] = lay.panel[npanel].develop(ALIGN_TOP);

                // We add the seams and hems allowance
                if (j == a)
                    dev.panel[npanel].addHems(seamW, hemsW, 0, 0);
                else
                    dev.panel[npanel].addHems(seamW, seamW, 0, 0);

                nps[h]++;
                npanel++;
            }

            // leech side lower central
            for (j=1; j<=a; j++)
            {
                pt1 = ptFoot + CVector3d (ptCentre - ptFoot)*(real(j-1)/(a));
                pt2 = clew;
                pt3 = ptFoot + CVector3d (ptCentre - ptFoot)*(real(j)/(a));
                pt4 = pt2;

                lay.panel[npanel].left.fill(pt1 , pt3);
                lay.panel[npanel].right.fill(pt2 , pt4);
                lay.panel[npanel].bottom.fill(pt1 , pt2);
                lay.panel[npanel].top.fill(pt3 , pt4);

                // compute Z
                for( k = 0; k < npl; k ++)
                    lay.panel[npanel].left.point[k] = Zpoint(lay.panel[npanel].left.point[k]);
                for( k = 0; k < npl; k ++)
                    lay.panel[npanel].right.point[k] = Zpoint(lay.panel[npanel].right.point[k]);
                for( k = 0; k < npb; k ++)
                    lay.panel[npanel].top.point[k] = Zpoint(lay.panel[npanel].top.point[k]);
                for( k = 0; k < npb; k ++)
                {
                    pt0 = lay.panel[npanel].bottom.point[k];
                    if (j == 1)
                        pt0 = FootIntersect(lay.panel[npanel].bottom.point[k], footVP);
                    lay.panel[npanel].bottom.point[k] = Zpoint(lay.panel[npanel].bottom.point[k]);
                }

                // We develop the current panel
                dev.panel[npanel] = lay.panel[npanel].develop(ALIGN_TOP);

                // We add the seams and hems allowance
                if (j == 1)
                    dev.panel[npanel].addHems(0, seamW, 0, hemsW);
                else
                    dev.panel[npanel].addHems(0, seamW, 0, 0);

                nps[h]++;
                npanel++;
            }

            // leech side central
            for (j=ng1/2+1; j<=ng1; j++)
            {
                pt1 = luffCatenary[h] + CVector3d(leechCatenary[h]-luffCatenary[h])*(real(j-1)/ng1);
                pt2 = clew ;

                pt3 = luffCatenary[h] + CVector3d(leechCatenary[h]-luffCatenary[h])*(real(j)/ng1);
                pt4 = pt2;

                lay.panel[npanel].left.fill(pt1 , pt3);
                lay.panel[npanel].right.fill(pt2 , pt4);
                lay.panel[npanel].bottom.fill(pt1 , pt2);
                lay.panel[npanel].top.fill(pt3 , pt4);

                // compute Z
                for( k = 0; k < npl; k ++)
                    lay.panel[npanel].left.point[k] = Zpoint(lay.panel[npanel].left.point[k]);
                for( k = 0; k < npl; k ++)
                    lay.panel[npanel].right.point[k] = Zpoint(lay.panel[npanel].right.point[k]);
                for( k = 0; k < npb; k ++)
                    lay.panel[npanel].top.point[k] = Zpoint(lay.panel[npanel].top.point[k]);
                for( k = 0; k < npb; k ++)
                    lay.panel[npanel].bottom.point[k] = Zpoint(lay.panel[npanel].bottom.point[k]);

                // We develop the current panel
                dev.panel[npanel] = lay.panel[npanel].develop(ALIGN_TOP);

                // We add the seams allowance
                dev.panel[npanel].addHems(seamW, seamW, 0, 0);

                nps[h]++;
                npanel++;
            }
        }

        /** cutting the leech side panels */
        for (j=1; j<nbGores-ngLuff; j++)
        {
            pt1 = leechCatenary[h] + CVector3d(leechH[h]-leechCatenary[h]) * (real(j-1)/(nbGores-ngLuff-1) );
            if (h == nbSections)
                pt1 = GaffIntersect( pt1, gaffVP );

            pt2 = leechCatenary[h-1] + CVector3d(leechH[h-1]-leechCatenary[h-1]) * (real(j-1)/(nbGores-ngLuff-1) );

            pt3 = leechCatenary[h] + CVector3d(leechH[h]-leechCatenary[h]) * (real(j)/(nbGores-ngLuff-1) );
            if (h == nbSections)
                pt3 = GaffIntersect( pt3, gaffVP );

            pt4 = leechCatenary[h-1] + CVector3d(leechH[h-1]-leechCatenary[h-1]) * (real(j)/(nbGores-ngLuff-1) );

            lay.panel[npanel].bottom.fill(pt1 , pt2);
            lay.panel[npanel].top.fill(pt3 , pt4);
            lay.panel[npanel].left.fill(pt1 , pt3);
            lay.panel[npanel].right.fill(pt2 , pt4);

            if (h == nbSections)
            {
                for (k=1; k<npl-1; k++)
                    lay.panel[npanel].left.point[k] = GaffIntersect(lay.panel[npanel].left.point[k], gaffVP );
            }

            if (j == nbGores-ngLuff-1)
            {
                for (k=1; k<npb-1; k++)
                    lay.panel[npanel].top.point[k] = LeechIntersect(lay.panel[npanel].top.point[k], CVector3d(luffH[h-1]-leechH[h-1]) );
            }

            // we compute Z
            for( k = 0; k < npl; k ++)
                lay.panel[npanel].left.point[k] = Zpoint(lay.panel[npanel].left.point[k]);
            for( k = 0; k < npl; k ++)
                lay.panel[npanel].right.point[k] = Zpoint(lay.panel[npanel].right.point[k]);
            for( k = 0; k < npb; k ++)
                lay.panel[npanel].top.point[k] = Zpoint(lay.panel[npanel].top.point[k]);
            for( k = 0; k < npb; k ++)
                lay.panel[npanel].bottom.point[k] = Zpoint(lay.panel[npanel].bottom.point[k]);

            // We develop the current panel
            dev.panel[npanel] = lay.panel[npanel].develop(ALIGN_TOP);

            // We add the seams and hems allowance
            if ( h == nbSections && j == nbGores-ngLuff-1)
                dev.panel[npanel].addHems(hemsW, leechHemW, 0, 0);
            else if (j == nbGores-ngLuff-1)
                dev.panel[npanel].addHems(seamW, leechHemW, 0, 0);
            else
                dev.panel[npanel].addHems(seamW, seamW, 0, 0);

            nps[h]++;
            npanel++;
        }
    }

    /** copying 3d lay into 3d sail */
    CSail sail(npanel);
    for( j = 0; j < npanel; j ++)
        sail.panel[j] = lay.panel[j];

    /* copying from temporary developed sail into flatsail */
    flatsail = CSail(npanel);

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

    /* prepare the displays version of the developed sail */
    dispsail = flatsail;
    j=0, h=nbSections, k=0;
    CRect3d pRect = dispsail.panel[j].boundingRect();
    v = CVector3d(0,0,0);
    xp = 0;
    xm = 0;
    ym = 0;

    for (j=0; j < npanel; j++)
    {
        if (k == nps[h])
        {
            // decrement section and offset x
            h--;
            k = 0;
            xp = xm + 2*seamW +20; // offset for next section
            v.x() = xp;
            v.y() = 0;
        }

        // translation v to stack panel above previous panel
        dispsail.panel[j] = dispsail.panel[j] + v;

        pRect = dispsail.panel[j].boundingRect();
        ym = pRect.height();
        v.y() += ym+ 2*seamW +20; // adding offset to separate next panel vertically

        x = pRect.max.x();
        if (x > xm)
            xm = x;
        k++;
    }
    ///
    return sail;
} ///////////// end layout radial cut ///////////////////////////////////


Generated by  Doxygen 1.6.0   Back to index