src/sel2.c
SELA *
selaAddCrossJunctions(SELA      *sela,
                      l_float32  hlsize,
                      l_float32  mdist,
                      l_int32    norient,
                      l_int32    debugflag)
{
char       name[L_BUF_SIZE];
l_int32    i, j, w, xc, yc;
l_float64  pi, halfpi, radincr, radang;
l_float64  angle;
PIX       *pixc, *pixm, *pixt;
PIXA      *pixa;
PTA       *pta1, *pta2, *pta3, *pta4;
SEL       *sel;

    PROCNAME("selaAddCrossJunctions");

    if (hlsize <= 0)
        return (SELA *)ERROR_PTR("hlsize not > 0", procName, NULL);
    if (norient < 1 || norient > 8)
        return (SELA *)ERROR_PTR("norient not in [1, ... 8]", procName, NULL);

    if (!sela) {
        if ((sela = selaCreate(0)) == NULL)
            return (SELA *)ERROR_PTR("sela not made", procName, NULL);
    }

    pi = 3.1415926535;
    halfpi = 3.1415926535 / 2.0;
    radincr = halfpi / (l_float64)norient;
    w = (l_int32)(2.2 * (L_MAX(hlsize, mdist) + 0.5));
    if (w % 2 == 0)
        w++;
    xc = w / 2;
    yc = w / 2;

    pixa = pixaCreate(norient);
    for (i = 0; i < norient; i++) {

            /* Set the don't cares */
        pixc = pixCreate(w, w, 32);
        pixSetAll(pixc);

            /* Add the green lines of hits */
        pixm = pixCreate(w, w, 1);
        radang = (l_float32)i * radincr;
        pta1 = generatePtaLineFromPt(xc, yc, hlsize + 1, radang);
        pta2 = generatePtaLineFromPt(xc, yc, hlsize + 1, radang + halfpi);
        pta3 = generatePtaLineFromPt(xc, yc, hlsize + 1, radang + pi);
        pta4 = generatePtaLineFromPt(xc, yc, hlsize + 1, radang + pi + halfpi);
        ptaJoin(pta1, pta2, 0, 0);
        ptaJoin(pta1, pta3, 0, 0);
        ptaJoin(pta1, pta4, 0, 0);
        pixRenderPta(pixm, pta1, L_SET_PIXELS);
        pixPaintThroughMask(pixc, pixm, 0, 0, 0x00ff0000);
        ptaDestroy(&pta1);
        ptaDestroy(&pta2);
        ptaDestroy(&pta3);
        ptaDestroy(&pta4);

            /* Add red misses between the lines */
        for (j = 0; j < 4; j++) {
            angle = radang + (j - 0.5) * halfpi;
            pixSetPixel(pixc, xc + (l_int32)(mdist * cos(angle)),
                        yc + (l_int32)(mdist * sin(angle)), 0xff000000);
        }

            /* Add dark green for origin */
        pixSetPixel(pixc, xc, yc, 0x00550000);

            /* Generate the sel */
        sel = selCreateFromColorPix(pixc, NULL);
        sprintf(name, "sel_cross_%d", i);
        selaAddSel(sela, sel, name, 0);

        if (debugflag) {
            pixt = pixScaleBySampling(pixc, 10.0, 10.0);
            pixaAddPix(pixa, pixt, L_INSERT);
        }
        pixDestroy(&pixm);
        pixDestroy(&pixc);
    }
    
    if (debugflag) {
        l_int32  w;
        pixaGetPixDimensions(pixa, 0, &w, NULL, NULL);
        pixt = pixaDisplayTiledAndScaled(pixa, 32, w, 1, 0, 10, 2);
        pixWriteTempfile("/tmp", "xsel1.png", pixt, IFF_PNG, 0);
        pixDisplay(pixt, 0, 100);
        pixDestroy(&pixt);
        pixt = selaDisplayInPix(sela, 15, 2, 20, 1);
        pixWriteTempfile("/tmp", "xsel2.png", pixt, IFF_PNG, 0);
        pixDisplay(pixt, 500, 100);
        pixDestroy(&pixt);
        selaWriteStream(stderr, sela);
    }
    pixaDestroy(&pixa);

    return sela;
}
/*!
 *  selaAddCrossJunctions()
 *
 *      Input:  sela (<optional>)
 *              hlsize (length of each line of hits from origin)
 *              mdist (distance of misses from the origin)
 *              norient (number of orientations; max of 8)
 *              debugflag (1 for debug output)
 *      Return: sela with additional sels, or null on error
 *
 *  Notes:
 *      (1) Adds hitmiss Sels for the intersection of two lines.
 *          If the lines are very thin, they must be nearly orthogonal
 *          to register.
 *      (2) The number of Sels generated is equal to @norient.
 *      (3) If @norient == 2, this generates 2 Sels of crosses, each with
 *          two perpendicular lines of hits.  One Sel has horizontal and
 *          vertical hits; the other has hits along lines at +-45 degrees.
 *          Likewise, if @norient == 3, this generates 3 Sels of crosses
 *          oriented at 30 degrees with each other.
 *      (4) It is suggested that @hlsize be chosen at least 1 greater
 *          than @mdist.  Try values of (@hlsize, @mdist) such as
 *          (6,5), (7,6), (8,7), (9,7), etc.
 */
selaAddCrossJunctions()
Input:  sela ()
hlsize (length of each line of hits from origin)
mdist (distance of misses from the origin)
norient (number of orientations; max of 8)
debugflag (1 for debug output)
Return: sela with additional sels, or null on error

(1) Adds hitmiss Sels for the intersection of two lines.
If the lines are very thin, they must be nearly orthogonal
to register.
(2) The number of Sels generated is equal to @norient.
(3) If @norient == 2, this generates 2 Sels of crosses, each with
two perpendicular lines of hits.  One Sel has horizontal and
vertical hits; the other has hits along lines at +-45 degrees.
Likewise, if @norient == 3, this generates 3 Sels of crosses
oriented at 30 degrees with each other.
(4) It is suggested that @hlsize be chosen at least 1 greater
than @mdist.
selaAddCrossJunctions () Input : sela () hlsize ( length of each line of hits from origin ) mdist ( distance of misses from the origin ) norient ( number of orientations ; max of 8 ) debugflag ( 1 for debug output ) Return : sela with additional sels or null on error ( 1 ) Adds hitmiss Sels for the intersection of two lines . If the lines are very thin they must be nearly orthogonal to register . ( 2 ) The number of Sels generated is equal to @norient . ( 3 ) If @norient == 2 this generates 2 Sels of crosses each with two perpendicular lines of hits . One Sel has horizontal and vertical hits ; the other has hits along lines at + - 45 degrees . Likewise if @norient == 3 this generates 3 Sels of crosses oriented at 30 degrees with each other . ( 4 ) It is suggested that @hlsize be chosen at least 1 greater than @mdist .
SELA *
selaAddCrossJunctions(SELA      *sela,
                      l_float32  hlsize,
                      l_float32  mdist,
                      l_int32    norient,
                      l_int32    debugflag)
{
char       name[L_BUF_SIZE];
l_int32    i, j, w, xc, yc;
l_float64  pi, halfpi, radincr, radang;
l_float64  angle;
PIX       *pixc, *pixm, *pixt;
PIXA      *pixa;
PTA       *pta1, *pta2, *pta3, *pta4;
SEL       *sel;
    PROCNAME("selaAddCrossJunctions");
    if (hlsize <= 0)
        return (SELA *)ERROR_PTR("hlsize not > 0", procName, NULL);
    if (norient < 1 || norient > 8)
        return (SELA *)ERROR_PTR("norient not in [1, ... 8]", procName, NULL);
    if (!sela) {
        if ((sela = selaCreate(0)) == NULL)
            return (SELA *)ERROR_PTR("sela not made", procName, NULL);
    }
    pi = 3.1415926535;
    halfpi = 3.1415926535 / 2.0;
    radincr = halfpi / (l_float64)norient;
    w = (l_int32)(2.2 * (L_MAX(hlsize, mdist) + 0.5));
    if (w % 2 == 0)
        w++;
    xc = w / 2;
    yc = w / 2;
    pixa = pixaCreate(norient);
    for (i = 0; i < norient; i++) {
        pixc = pixCreate(w, w, 32);
        pixSetAll(pixc);
        pixm = pixCreate(w, w, 1);
        radang = (l_float32)i * radincr;
        pta1 = generatePtaLineFromPt(xc, yc, hlsize + 1, radang);
        pta2 = generatePtaLineFromPt(xc, yc, hlsize + 1, radang + halfpi);
        pta3 = generatePtaLineFromPt(xc, yc, hlsize + 1, radang + pi);
        pta4 = generatePtaLineFromPt(xc, yc, hlsize + 1, radang + pi + halfpi);
        ptaJoin(pta1, pta2, 0, 0);
        ptaJoin(pta1, pta3, 0, 0);
        ptaJoin(pta1, pta4, 0, 0);
        pixRenderPta(pixm, pta1, L_SET_PIXELS);
        pixPaintThroughMask(pixc, pixm, 0, 0, 0x00ff0000);
        ptaDestroy(&pta1);
        ptaDestroy(&pta2);
        ptaDestroy(&pta3);
        ptaDestroy(&pta4);
        for (j = 0; j < 4; j++) {
            angle = radang + (j - 0.5) * halfpi;
            pixSetPixel(pixc, xc + (l_int32)(mdist * cos(angle)),
                        yc + (l_int32)(mdist * sin(angle)), 0xff000000);
        }
        pixSetPixel(pixc, xc, yc, 0x00550000);
        sel = selCreateFromColorPix(pixc, NULL);
        sprintf(name, "sel_cross_%d", i);
        selaAddSel(sela, sel, name, 0);
        if (debugflag) {
            pixt = pixScaleBySampling(pixc, 10.0, 10.0);
            pixaAddPix(pixa, pixt, L_INSERT);
        }
        pixDestroy(&pixm);
        pixDestroy(&pixc);
    }
    if (debugflag) {
        l_int32  w;
        pixaGetPixDimensions(pixa, 0, &w, NULL, NULL);
        pixt = pixaDisplayTiledAndScaled(pixa, 32, w, 1, 0, 10, 2);
        pixWriteTempfile("/tmp", "xsel1.png", pixt, IFF_PNG, 0);
        pixDisplay(pixt, 0, 100);
        pixDestroy(&pixt);
        pixt = selaDisplayInPix(sela, 15, 2, 20, 1);
        pixWriteTempfile("/tmp", "xsel2.png", pixt, IFF_PNG, 0);
        pixDisplay(pixt, 500, 100);
        pixDestroy(&pixt);
        selaWriteStream(stderr, sela);
    }
    pixaDestroy(&pixa);
    return sela;
}
SELA * selaAddCrossJunctions ( SELA * sela , l_float32 hlsize , l_float32 mdist , l_int32 norient , l_int32 debugflag ) { char name [ L_BUF_SIZE ] ; l_int32 i , j , w , xc , yc ; l_float64 pi , halfpi , radincr , radang ; l_float64 angle ; PIX * pixc , * pixm , * pixt ; PIXA * pixa ; PTA * pta1 , * pta2 , * pta3 , * pta4 ; SEL * sel ; PROCNAME ( " " ) ; if ( hlsize <= 0 ) return ( SELA * ) ERROR_PTR ( " " , procName , NULL ) ; if ( norient < 1 || norient > 8 ) return ( SELA * ) ERROR_PTR ( " " , procName , NULL ) ; if ( ! sela ) { if ( ( sela = selaCreate ( 0 ) ) == NULL ) return ( SELA * ) ERROR_PTR ( " " , procName , NULL ) ; } pi = 3.1415926535 ; halfpi = 3.1415926535 / 2.0 ; radincr = halfpi / ( l_float64 ) norient ; w = ( l_int32 ) ( 2.2 * ( L_MAX ( hlsize , mdist ) + 0.5 ) ) ; if ( w % 2 == 0 ) w ++ ; xc = w / 2 ; yc = w / 2 ; pixa = pixaCreate ( norient ) ; for ( i = 0 ; i < norient ; i ++ ) { pixc = pixCreate ( w , w , 32 ) ; pixSetAll ( pixc ) ; pixm = pixCreate ( w , w , 1 ) ; radang = ( l_float32 ) i * radincr ; pta1 = generatePtaLineFromPt ( xc , yc , hlsize + 1 , radang ) ; pta2 = generatePtaLineFromPt ( xc , yc , hlsize + 1 , radang + halfpi ) ; pta3 = generatePtaLineFromPt ( xc , yc , hlsize + 1 , radang + pi ) ; pta4 = generatePtaLineFromPt ( xc , yc , hlsize + 1 , radang + pi + halfpi ) ; ptaJoin ( pta1 , pta2 , 0 , 0 ) ; ptaJoin ( pta1 , pta3 , 0 , 0 ) ; ptaJoin ( pta1 , pta4 , 0 , 0 ) ; pixRenderPta ( pixm , pta1 , L_SET_PIXELS ) ; pixPaintThroughMask ( pixc , pixm , 0 , 0 , 0x00ff0000 ) ; ptaDestroy ( & pta1 ) ; ptaDestroy ( & pta2 ) ; ptaDestroy ( & pta3 ) ; ptaDestroy ( & pta4 ) ; for ( j = 0 ; j < 4 ; j ++ ) { angle = radang + ( j - 0.5 ) * halfpi ; pixSetPixel ( pixc , xc + ( l_int32 ) ( mdist * cos ( angle ) ) , yc + ( l_int32 ) ( mdist * sin ( angle ) ) , 0xff000000 ) ; } pixSetPixel ( pixc , xc , yc , 0x00550000 ) ; sel = selCreateFromColorPix ( pixc , NULL ) ; sprintf ( name , " " , i ) ; selaAddSel ( sela , sel , name , 0 ) ; if ( debugflag ) { pixt = pixScaleBySampling ( pixc , 10.0 , 10.0 ) ; pixaAddPix ( pixa , pixt , L_INSERT ) ; } pixDestroy ( & pixm ) ; pixDestroy ( & pixc ) ; } if ( debugflag ) { l_int32 w ; pixaGetPixDimensions ( pixa , 0 , & w , NULL , NULL ) ; pixt = pixaDisplayTiledAndScaled ( pixa , 32 , w , 1 , 0 , 10 , 2 ) ; pixWriteTempfile ( " " , " " , pixt , IFF_PNG , 0 ) ; pixDisplay ( pixt , 0 , 100 ) ; pixDestroy ( & pixt ) ; pixt = selaDisplayInPix ( sela , 15 , 2 , 20 , 1 ) ; pixWriteTempfile ( " " , " " , pixt , IFF_PNG , 0 ) ; pixDisplay ( pixt , 500 , 100 ) ; pixDestroy ( & pixt ) ; selaWriteStream ( stderr , sela ) ; } pixaDestroy ( & pixa ) ; return sela ; }
selaAddCrossJunctions()
      Input:  sela (<optional>)
              hlsize (length of each line of hits from origin)
              mdist (distance of misses from the origin)
              norient (number of orientations; max of 8)
              debugflag (1 for debug output)
      Return: sela with additional sels, or null on error
selaAddCrossJunctions () Input : sela ( <optional > ) hlsize ( length of each line of hits from origin ) mdist ( distance of misses from the origin ) norient ( number of orientations ; max of 8 ) debugflag ( 1 for debug output ) Return : sela with additional sels or null on error
/* Set the don't cares */ /* Add the green lines of hits */ /* Add red misses between the lines */ /* Add dark green for origin */ /* Generate the sel */