Annotation of researchv10no/cmd/ideal/opqpoly.c, revision 1.1

1.1     ! root        1: #include "ideal.h"
        !             2: #include "y.tab.h"
        !             3: 
        !             4: extern float interalpha[INTERSIZE];
        !             5: extern int internum;
        !             6: 
        !             7: void opqpoly (edgelist, linelist, inlines, outlines, both)
        !             8: EDGEPTR edgelist;
        !             9: LINEPTR linelist;
        !            10: LINEPTR *inlines, *outlines, *both;
        !            11: {
        !            12:        LINEPTR linewalk, circlearc;
        !            13:        LINENODE nuin, nuout, nuboth;
        !            14:        LINEPTR inwalk, outwalk, bothwalk;
        !            15:        LINEPTR forfreeing;
        !            16: 
        !            17:        inwalk = &nuin;
        !            18:        inwalk->next = NULL;
        !            19:        outwalk = &nuout;
        !            20:        outwalk->next = NULL;
        !            21:        bothwalk = &nuboth;
        !            22:        bothwalk->next = NULL;
        !            23:        linewalk = linelist;
        !            24:        while (linewalk) {
        !            25:                while (inwalk->next)
        !            26:                        inwalk = inwalk->next;
        !            27:                while (outwalk->next)
        !            28:                        outwalk = outwalk->next;
        !            29:                while (bothwalk->next)
        !            30:                        bothwalk = bothwalk->next;
        !            31:                switch (linewalk->kind) {
        !            32:                case LINE:
        !            33:                        polyline (
        !            34:                                edgelist,
        !            35:                                linewalk->x0,
        !            36:                                linewalk->y0,
        !            37:                                linewalk->x1,
        !            38:                                linewalk->y1,
        !            39:                                &inwalk->next,
        !            40:                                &outwalk->next,
        !            41:                                &bothwalk->next
        !            42:                        );
        !            43:                        forfreeing = linewalk;
        !            44:                        linewalk = linewalk->next;
        !            45:                        tryfree(forfreeing);
        !            46:                        break;
        !            47:                case CIRCLE:
        !            48:                        circlearc = angularc (
        !            49:                                ((CIRCPTR) linewalk)->x0,
        !            50:                                ((CIRCPTR) linewalk)->y0,
        !            51:                                ((CIRCPTR) linewalk)->r,
        !            52:                                0.0,
        !            53:                                2.0*PI
        !            54:                        );
        !            55:                        circlearc->next = linewalk->next;
        !            56:                        tryfree(linewalk);
        !            57:                        linewalk = circlearc;
        !            58:                        /* FALL THROUGH TO case arc */
        !            59:                case ARC:
        !            60:                        polyarc (
        !            61:                                edgelist,
        !            62:                                ((ARCPTR) linewalk)->x0,
        !            63:                                ((ARCPTR) linewalk)->y0,
        !            64:                                ((ARCPTR) linewalk)->radius,
        !            65:                                ((ARCPTR) linewalk)->theta1,
        !            66:                                ((ARCPTR) linewalk)->theta2,
        !            67:                                &inwalk->next,
        !            68:                                &outwalk->next,
        !            69:                                &bothwalk->next
        !            70:                        );
        !            71:                        forfreeing = linewalk;
        !            72:                        linewalk = linewalk->next;
        !            73:                        tryfree(forfreeing);
        !            74:                        break;
        !            75:                case STRING:
        !            76: /*
        !            77:                        fprintf (stderr, "ideal: can't opaque over strings\n");
        !            78: */
        !            79:                        bothwalk->next = linewalk;
        !            80:                        linewalk = linewalk->next;
        !            81:                        bothwalk->next->next = NULL;
        !            82:                        break;
        !            83:                case SPLINE:
        !            84: /*
        !            85:                        fprintf (stderr, "ideal: can't opaque over splines\n");
        !            86: */
        !            87:                        bothwalk->next = linewalk;
        !            88:                        linewalk = linewalk->next;
        !            89:                        bothwalk->next->next = NULL;
        !            90:                        break;
        !            91:                default:
        !            92:                        impossible ("opqpoly");
        !            93:                        break;
        !            94:                } /* switch */
        !            95:        } /* while */
        !            96:        *inlines = nuin.next;
        !            97:        *outlines = nuout.next;
        !            98:        *both = nuboth.next;
        !            99: } /* opqpoly */
        !           100: 
        !           101: boolean oppose (x0, y0, x1, y1, px0, py0, px1, py1)
        !           102: float x0, y0, x1, y1, px0, py0, px1, py1;
        !           103: {
        !           104:        /* returns TRUE iff
        !           105:        /* p0 and p1 lie on opposite sides of the line through points 0,1 */
        !           106:        float alpha, beta;
        !           107:        boolean collinear;
        !           108: 
        !           109:        if (llinter (
        !           110:                x0, y0, x1, y1,
        !           111:                px0, py0, px1, py1,
        !           112:                &alpha, &beta, &collinear
        !           113:        )) {
        !           114:                if (beta < EPSILON)
        !           115:                        return FALSE;
        !           116:                if (beta > 1.0-EPSILON)
        !           117:                        return FALSE;
        !           118:                return TRUE;
        !           119:        } else
        !           120:                return FALSE;
        !           121: }
        !           122: 
        !           123: boolean lcross (cx0, cy0, cx1, cy1,
        !           124:        px0, py0, qx0, qy0, tx0, ty0,
        !           125:        px1, py1, qx1, qy1, tx1, ty1)
        !           126: float cx0, cy0, cx1, cy1,
        !           127:        px0, py0, qx0, qy0, tx0, ty0,
        !           128:        px1, py1, qx1, qy1, tx1, ty1;
        !           129: {
        !           130:        /* line goes through c0 and c1
        !           131:        /* p0 and p1 lie on line
        !           132:        /* q0 and q1 are other ends of edges
        !           133:        /* t0 and t1 are tangents to edges at p0 and p1
        !           134:        /* returns TRUE iff line crosses edges at p0--p1 */
        !           135:        float x0, y0, x1, y1;
        !           136:        if (arecollinear(cx0, cy0, cx1, cy1, tx0, ty0)) {
        !           137:                x0 = qx0;
        !           138:                y0 = qy0;
        !           139:        } else {
        !           140:                x0 = tx0;
        !           141:                y0 = ty0;
        !           142:        }
        !           143:        if (arecollinear(cx0, cy0, cx1, cy1, tx1, ty1)) {
        !           144:                x1 = qx1;
        !           145:                y1 = qy1;
        !           146:        } else {
        !           147:                x1 = tx1;
        !           148:                y1 = ty1;
        !           149:        }
        !           150:        return oppose (cx0, cy0, cx1, cy1, x0, y0, x1, y1);
        !           151: }
        !           152: 
        !           153: void polyline (edgelist, candx0,candy0, candx1,candy1, inlines, outlines, both)
        !           154: EDGEPTR edgelist;
        !           155: float candx0,candy0, candx1,candy1;
        !           156: LINEPTR *inlines, *outlines, *both;
        !           157: {
        !           158:        OPQPTR interwalk;
        !           159:        boolean inside, onedge;
        !           160:        LINENODE nuin, nuout;
        !           161:        LINEPTR inwalk, outwalk;
        !           162:        LINEPTR linewalk;
        !           163:        EDGEPTR prevedge, curedge;
        !           164:        OPQPTR alphalist;
        !           165:        float alpha, beta;
        !           166:        float gamma[2], theta[2];
        !           167:        boolean collinear;
        !           168:        boolean X, Y, Z, W;
        !           169:        int i;
        !           170:        double dummy, rem;
        !           171: 
        !           172:        alphalist = (OPQPTR) NULL;
        !           173:        inwalk = &nuin;
        !           174:        inwalk->next = NULL;
        !           175:        outwalk = &nuout;
        !           176:        outwalk->next = NULL;
        !           177:        curedge = edgelist;
        !           178:        do {
        !           179:                if (curedge->fax == NULL) {
        !           180:                        if (
        !           181:                                llinter (
        !           182:                                        candx0, candy0,
        !           183:                                        candx1, candy1,
        !           184:                                        curedge->sx, curedge->sy,
        !           185:                                        curedge->ex, curedge->ey,
        !           186:                                        &alpha,
        !           187:                                        &beta,
        !           188:                                        &collinear
        !           189:                                )
        !           190:                        ) {
        !           191:                                if (EPSILON < beta && beta < 1.0 - EPSILON)
        !           192:                                        curedge->code[0] = SIMPLE;
        !           193:                                else if (fabs(beta) < EPSILON)
        !           194:                                        curedge->code[0] = AT0;
        !           195:                                else if (fabs(1.0-beta) < EPSILON)
        !           196:                                        curedge->code[0] = AT1;
        !           197:                                else
        !           198:                                        curedge->code[0] = UNUSED;
        !           199:                                curedge->alpha[0] = alpha;
        !           200:                                curedge->code[1] = UNUSED;
        !           201:                        } else
        !           202:                                if (collinear) {
        !           203:                                        if (fabs(candx1 - candx0) < EPSILON) {
        !           204:                                                curedge->alpha[0] = (curedge->sy - candy0)/(candy1 - candy0);
        !           205:                                                curedge->alpha[1] = (curedge->ey - candy0)/(candy1 - candy0);
        !           206:                                        } else {
        !           207:                                                curedge->alpha[0] = (curedge->sx - candx0)/(candx1 - candx0);
        !           208:                                                curedge->alpha[1] = (curedge->ex - candx0)/(candx1 - candx0);
        !           209:                                        }
        !           210:                                        if (curedge->alpha[0] < curedge->alpha[1]) {
        !           211:                                                curedge->code[0] = ON0;
        !           212:                                                curedge->code[1] = ON1;
        !           213:                                        } else {
        !           214:                                                curedge->code[0] = ON1;
        !           215:                                                curedge->code[1] = ON0;
        !           216:                                        }
        !           217:                                } else
        !           218:                                        curedge->code[0] = curedge->code[1] = UNUSED;
        !           219:                } else if (curedge->fax->kind == ARC) {
        !           220:                        if (
        !           221:                                !lcinter (
        !           222:                                        candx0, candy0,
        !           223:                                        candx1, candy1,
        !           224:                                        curedge->fax->x0, curedge->fax->y0,
        !           225:                                        fabs(curedge->fax->radius),
        !           226:                                        &gamma[0], &theta[0],
        !           227:                                        &gamma[1], &theta[1]
        !           228:                                )
        !           229:                        ) {
        !           230:                                curedge->code[0] = curedge->code[1] = UNUSED;
        !           231:                                dprintf "line outside circle\n");
        !           232:                        } else if (fabs(theta[0] - theta[1]) < EPSILON) {
        !           233:                                if (fabs(theta[0] - curedge->fax->theta1) < EPSILON) {
        !           234:                                        curedge->alpha[0] = gamma[0];
        !           235:                                        curedge->code[0] = curedge->flipped?AT1:AT0;
        !           236:                                        dprintf "%d\n", curedge->code[0]);
        !           237:                                } else if (fabs(theta[0] - curedge->fax->theta2) < EPSILON) {
        !           238:                                        curedge->alpha[0] = gamma[0];
        !           239:                                        curedge->code[0] = curedge->flipped?AT0:AT1;
        !           240:                                        dprintf "%d\n", curedge->code[0]);
        !           241:                                } else {
        !           242:                                        curedge->code[0] = UNUSED;
        !           243:                                        dprintf "line tangent\n");
        !           244:                                }
        !           245:                                curedge->code[1] = UNUSED;
        !           246:                        } else {
        !           247:                                for (i = 0; i < 2; i ++) {
        !           248:                                        dprintf "disposition of %f\n", theta[i]);
        !           249:                                        if (curedge->fax->theta2 < 2.0*PI) {
        !           250:                                                if (theta[i] - curedge->fax->theta1 < -EPSILON
        !           251:                                                        || curedge->fax->theta2 - theta[i] < -EPSILON) {
        !           252:                                                        curedge->code[i] = UNUSED;
        !           253:                                                        dprintf "intersection off arc\n");
        !           254:                                                        continue;
        !           255:                                                }
        !           256:                                        }
        !           257:                                        if (curedge->fax->theta2 >= 2.0*PI) {
        !           258:                                                if (theta[i] - curedge->fax->theta1 < -EPSILON
        !           259:                                                        && curedge->fax->theta2 - theta[i] < 2.0*PI - EPSILON) {
        !           260:                                                        curedge->code[i] = UNUSED;
        !           261:                                                        dprintf "intersection off arc\n");
        !           262:                                                        continue;
        !           263:                                                }
        !           264:                                        }
        !           265:                                        rem = modf(fabs(theta[i] - curedge->fax->theta1)/(2*PI), &dummy);
        !           266:                                        dprintf "rem1 = %f\n", rem);
        !           267:                                        if (rem < EPSILON || fabs(1.0-rem) < EPSILON) {
        !           268:                                                curedge->alpha[i] = gamma[i];
        !           269:                                                curedge->code[i] = curedge->flipped?AT1:AT0;
        !           270:                                                dprintf "%d\n", curedge->code[i]);
        !           271:                                                continue;
        !           272:                                        }
        !           273:                                        rem = modf(fabs(theta[i] - curedge->fax->theta2)/(2*PI), &dummy);
        !           274:                                        dprintf "rem2 = %f\n", rem);
        !           275:                                        if (rem < EPSILON || fabs(1.0-rem) < EPSILON) {
        !           276:                                                curedge->alpha[i] = gamma[i];
        !           277:                                                curedge->code[i] = curedge->flipped?AT0:AT1;
        !           278:                                                dprintf "%d\n", curedge->code[i]);
        !           279:                                                continue;
        !           280:                                        }
        !           281:                                        dprintf "simple\n");
        !           282:                                        curedge->code[i] = SIMPLE;
        !           283:                                        curedge->alpha[i] = gamma[i];
        !           284:                                }
        !           285:                        }
        !           286:                } else
        !           287:                        impossible ("polyline(A)");
        !           288:                curedge = curedge->next;
        !           289:        } while (curedge != edgelist);
        !           290:        if (dbg) {
        !           291:                curedge = edgelist;
        !           292:                do {
        !           293:                        fprintf (stderr, "s (%f,%f); e (%f,%f)\n",
        !           294:                                curedge->sx, curedge->sy,
        !           295:                                curedge->ex, curedge->ey
        !           296:                        );
        !           297:                        fprintf (stderr, "st (%f,%f); et (%f,%f)\n",
        !           298:                                curedge->stx, curedge->sty,
        !           299:                                curedge->etx, curedge->ety
        !           300:                        );
        !           301:                        for (i = 0; i < POSSINTER; i ++)
        !           302:                                fprintf (stderr, "%d %f\n",
        !           303:                                        curedge->code[i],
        !           304:                                        curedge->alpha[i]
        !           305:                                );
        !           306:                        curedge = curedge->next;
        !           307:                } while (curedge != edgelist);
        !           308:        }
        !           309:        prevedge = edgelist;
        !           310:        curedge = edgelist->next;
        !           311:        do {
        !           312:                for (i = 0; i < POSSINTER; i ++)
        !           313:                        switch (curedge->code[i]) {
        !           314:                        case UNUSED:
        !           315:                                break;
        !           316:                        case SIMPLE:
        !           317:                                opqinsert(SIMPLE, curedge->alpha[i], &alphalist);
        !           318:                                break;
        !           319:                        case AT0:
        !           320:                                if (lcross (
        !           321:                                        candx0, candy0, candx1, candy1,
        !           322:                                        curedge->sx, curedge->sy,
        !           323:                                        curedge->ex, curedge->ey,
        !           324:                                        curedge->stx, curedge->sty,
        !           325:                                        prevedge->ex, prevedge->ey,
        !           326:                                        prevedge->sx, prevedge->sy,
        !           327:                                        prevedge->etx, prevedge->ety
        !           328:                                ))
        !           329:                                        opqinsert(SIMPLE, curedge->alpha[i], &alphalist);
        !           330:                                break;
        !           331:                        case AT1:
        !           332:                                /* should be taken care of by next AT0 */
        !           333:                                break;
        !           334:                        case ON0:
        !           335:                        case ON1:
        !           336:                                if (lcross (
        !           337:                                        candx0, candy0, candx1, candy1,
        !           338:                                        prevedge->ex, prevedge->ey,
        !           339:                                        prevedge->sx, prevedge->sy,
        !           340:                                        prevedge->etx, prevedge->ety,
        !           341:                                        curedge->next->sx, curedge->next->sy,
        !           342:                                        curedge->next->ex, curedge->next->ey,
        !           343:                                        curedge->next->stx, curedge->next->sty
        !           344:                                ))
        !           345:                                        opqinsert(INFL0, curedge->alpha[i], &alphalist);
        !           346:                                else
        !           347:                                        opqinsert(EXT0, curedge->alpha[i], &alphalist);
        !           348:                                break;
        !           349:                        case TANGENT:
        !           350:                        default:
        !           351:                                impossible ("polyline(B)");
        !           352:                                break;
        !           353:                        }
        !           354:                prevedge = curedge;
        !           355:                curedge = curedge->next;
        !           356:        } while (prevedge != edgelist);
        !           357:        opqinsert(INHERIT, 0.0, &alphalist);
        !           358:        opqinsert(INHERIT, 1.0, &alphalist);
        !           359:        if (dbg) {
        !           360:                fprintf (stderr, "interalpha:\n");
        !           361:                for (interwalk = alphalist;
        !           362:                        interwalk;
        !           363:                        interwalk = interwalk->next)
        !           364:                        fprintf (stderr, "%d %f, ", interwalk->code, interwalk->alpha);
        !           365:                fprintf (stderr, "\n");
        !           366:        }
        !           367:        inside = onedge = FALSE;
        !           368:        for (interwalk = alphalist; interwalk; interwalk = interwalk->next)
        !           369:                switch (interwalk->code) {
        !           370:                case SIMPLE:
        !           371:                        inside = !inside;
        !           372:                        interwalk->code = inside?INBEGIN:OUTBEGIN;
        !           373:                        break;
        !           374:                case EXT1:
        !           375:                case EXT0:
        !           376:                        onedge = !onedge;
        !           377:                        interwalk->code = onedge?ONBEGIN:inside?INBEGIN:OUTBEGIN;
        !           378:                        break;
        !           379:                case INFL1:
        !           380:                case INFL0:
        !           381:                        onedge = !onedge;
        !           382:                        if (onedge)
        !           383:                                interwalk->code = ONBEGIN;
        !           384:                        else {
        !           385:                                inside = !inside;
        !           386:                                interwalk->code = inside?INBEGIN:OUTBEGIN;
        !           387:                        }
        !           388:                        break;
        !           389:                case INHERIT:
        !           390:                case IGNORE:
        !           391:                        interwalk->code = onedge?ONBEGIN:inside?INBEGIN:OUTBEGIN;
        !           392:                        break;
        !           393:                        break;
        !           394:                default:
        !           395:                        impossible("polyline(C)");
        !           396:                        break;
        !           397:                }
        !           398:        if (dbg) {
        !           399:                fprintf (stderr, "interalpha:\n");
        !           400:                for (interwalk = alphalist;
        !           401:                        interwalk;
        !           402:                        interwalk = interwalk->next)
        !           403:                        fprintf (stderr, "%d %f, ", interwalk->code, interwalk->alpha);
        !           404:                fprintf (stderr, "\n");
        !           405:        }
        !           406:        for (interwalk = alphalist; interwalk; interwalk = interwalk->next) {
        !           407:                linewalk = linegen (
        !           408:                        candx0 + interwalk->alpha*(candx1 - candx0),
        !           409:                        candy0 + interwalk->alpha*(candy1 - candy0),
        !           410:                        candx0 + interwalk->next->alpha*(candx1 - candx0),
        !           411:                        candy0 + interwalk->next->alpha*(candy1 - candy0)
        !           412:                );
        !           413:                if (
        !           414:                        interwalk->alpha > -EPSILON
        !           415:                        && interwalk->next
        !           416:                        && interwalk->next->alpha < 1.0 + EPSILON
        !           417:                )
        !           418:                        switch (interwalk->code) {
        !           419:                        case INBEGIN:
        !           420:                                inwalk->next = linewalk;
        !           421:                                inwalk = inwalk->next;
        !           422:                                break;
        !           423:                        case OUTBEGIN:
        !           424:                                outwalk->next = linewalk;       
        !           425:                                outwalk = outwalk->next;
        !           426:                                break;
        !           427:                        case ONBEGIN:
        !           428:                                tryfree(linewalk);
        !           429:                                break;
        !           430:                        default:
        !           431:                                impossible("polyline(D)");
        !           432:                                break;
        !           433:                        }
        !           434:        }
        !           435:        *inlines = nuin.next;
        !           436:        *outlines = nuout.next;
        !           437:        *both = NULL;
        !           438: }
        !           439: 
        !           440: #define        xtanp(x,y,r,t)  x+fabs(r)*cos(t)+sin(t)
        !           441: #define        ytanp(x,y,r,t)  y+fabs(r)*sin(t)-cos(t)
        !           442: #define        xtane(x,y,r,t)  x+fabs(r)*cos(t)-sin(t)
        !           443: #define        ytane(x,y,r,t)  y+fabs(r)*sin(t)+cos(t)
        !           444: 
        !           445: boolean ptinpoly (edgelist, x, y)
        !           446: EDGEPTR edgelist;
        !           447: float x, y;
        !           448: {
        !           449:        LINEPTR inlines, outlines, both;
        !           450:        polyline (
        !           451:                edgelist,
        !           452:                x - 100*EPSILON, y - 100*EPSILON,
        !           453:                x + 100*EPSILON, y + 100*EPSILON,
        !           454:                &inlines, &outlines, &both
        !           455:        );
        !           456:        if (inlines) {
        !           457:                if (outlines || both)
        !           458:                        impossible ("ptinpoly(A)");
        !           459:                else {
        !           460:                        linefree(inlines);
        !           461:                        dprintf "ptinpoly: TRUE\n");
        !           462:                        return TRUE;
        !           463:                }
        !           464:        } else if (outlines) {
        !           465:                if (inlines || both)
        !           466:                        impossible ("ptinpoly(B)");
        !           467:                else {
        !           468:                        linefree(outlines);
        !           469:                        dprintf "ptinpoly: FALSE\n");
        !           470:                        return FALSE;
        !           471:                }
        !           472:        } else
        !           473:                impossible ("ptinpoly(C)");
        !           474: }
        !           475: 
        !           476: boolean locin (x0, y0, r,
        !           477:        qx, qy, tx, ty,
        !           478:        t1x, t1y, t2x, t2y)
        !           479: float x0, y0, r, qx, qy, tx, ty, t1x, t1y, t2x, t2y;
        !           480: {
        !           481:        dprintf "locin\n");
        !           482:        if (arecollinear(tx,ty,t1x,t1y,t2x,t2y)) {
        !           483:                dprintf "arecollinear TRUE\n");
        !           484:                return (hypot(x0-qx,y0-qy) < fabs(r));
        !           485:        } else
        !           486:                return !oppose(x0,y0,tx,ty,t1x,t1y,t2x,t2y);
        !           487: }
        !           488: 
        !           489: boolean ccross (x0, y0, r,
        !           490:        p1x, p1y, q1x, q1y, t1x, t1y,
        !           491:        p2x, p2y, q2x, q2y, t2x, t2y)
        !           492: float x0, y0, r, p1x, p1y, q1x, q1y, t1x, t1y, p2x, p2y, q2x, q2y, t2x, t2y;
        !           493: {
        !           494:        float theta1, theta2;
        !           495:        boolean in1, in2;
        !           496:        float xt1, yt1, xt2, yt2;
        !           497:        dprintf "ccross: %f %f  %f\n", x0, y0, r);
        !           498:        dprintf "ccross: %f %f  %f %f\n", p1x, p1y, p2x, p2y);
        !           499:        theta1 = atan2(p1y-y0,p1x-x0);
        !           500:        theta2 = atan2(p2y-y0,p2x-x0);
        !           501:        dprintf "ccross: theta1 = %f; theta2 = %f\n", theta1, theta2);
        !           502:        xt1 = xtanp(x0,y0,r,theta1);
        !           503:        yt1 = ytanp(x0,y0,r,theta1);
        !           504:        xt2 = xtane(x0,y0,r,theta1);
        !           505:        yt2 = ytane(x0,y0,r,theta1);
        !           506:        dprintf "1:xt1 = %f; yt1 = %f; xt2 = %f; yt2 = %f\n", xt1, yt1, xt2, yt2);
        !           507:        in1 = locin(x0,y0,r,
        !           508:                        q1x,q1y,t1x,t1y,
        !           509:                        xt1, yt1, xt2, yt2
        !           510:                );
        !           511:        xt1 = xtanp(x0,y0,r,theta2);
        !           512:        yt1 = ytanp(x0,y0,r,theta2);
        !           513:        xt2 = xtane(x0,y0,r,theta2);
        !           514:        yt2 = ytane(x0,y0,r,theta2);
        !           515:        dprintf "2:xt1 = %f; yt1 = %f; xt2 = %f; yt2 = %f\n", xt1, yt1, xt2, yt2);
        !           516:        in2 = locin(x0,y0,r,
        !           517:                        q2x,q2y,t2x,t2y,
        !           518:                        xt1, yt1, xt2, yt2
        !           519:                );
        !           520:        dprintf "ccross: in1 = %d; in2 = %d\n", in1, in2);
        !           521:        return in1 ^ in2;
        !           522: }
        !           523: 
        !           524: void polyarc (edgelist, x0,y0, radius, startang, endang, inlines, outlines, both)
        !           525: EDGEPTR edgelist;
        !           526: float x0, y0, radius, startang, endang;
        !           527: LINEPTR *inlines, *outlines, *both;
        !           528: {
        !           529:        OPQPTR interwalk;
        !           530:        boolean inside, onedge;
        !           531:        LINENODE nuin, nuout;
        !           532:        LINEPTR inwalk, outwalk;
        !           533:        LINEPTR linewalk;
        !           534:        EDGEPTR prevedge, curedge;
        !           535:        OPQPTR alphalist;
        !           536:        float alpha[2], beta[2], gamma[2], theta[2];
        !           537:        boolean collinear;
        !           538:        boolean X, Y, Z, W;
        !           539:        float stx, sty, etx, ety;
        !           540:        int i;
        !           541:        double dummy, rem;
        !           542: 
        !           543:        alphalist = (OPQPTR) NULL;
        !           544:        inwalk = &nuin;
        !           545:        inwalk->next = NULL;
        !           546:        outwalk = &nuout;
        !           547:        outwalk->next = NULL;
        !           548:        curedge = edgelist;
        !           549:        do {
        !           550:                if (curedge->fax == NULL) {
        !           551:                        if (
        !           552:                                lcinter (
        !           553:                                        curedge->sx, curedge->sy,
        !           554:                                        curedge->ex, curedge->ey,
        !           555:                                        x0, y0,
        !           556:                                        radius,
        !           557:                                        &alpha[0], &theta[0],
        !           558:                                        &alpha[1], &theta[1]
        !           559:                                )
        !           560:                        ) {
        !           561:                                if (fabs(theta[0] - theta[1]) < EPSILON) {
        !           562:                                        if (fabs(alpha[0]) < EPSILON)
        !           563:                                                curedge->code[0] = AT0;
        !           564:                                        else if (fabs(1.0-alpha[0]) < EPSILON)
        !           565:                                                curedge->code[0] = AT1;
        !           566:                                        else
        !           567:                                                curedge->code[0] = TANGENT;
        !           568:                                        curedge->alpha[0] = rprin(theta[0]);
        !           569:                                        curedge->code[1] = UNUSED;
        !           570:                                } else {
        !           571:                                        for (i = 0; i < 2; i ++) {
        !           572:                                                if (EPSILON < alpha[i] && alpha[i] < 1.0 - EPSILON)
        !           573:                                                        curedge->code[i] = SIMPLE;
        !           574:                                                else if (fabs(alpha[i]) < EPSILON)
        !           575:                                                        curedge->code[i] = AT0;
        !           576:                                                else if (fabs(alpha[i] - 1.0) < EPSILON)
        !           577:                                                        curedge->code[i] = AT1;
        !           578:                                                else
        !           579:                                                        curedge->code[i] = UNUSED;
        !           580:                                                curedge->alpha[i] = rprin(theta[i]);
        !           581:                                        }
        !           582:                                }
        !           583:                        } else {
        !           584:                                curedge->code[0] = curedge->code[1] = UNUSED;
        !           585:                        }
        !           586:                } else if (curedge->fax->kind == ARC) {
        !           587:                        if (!ccinter (
        !           588:                                        x0, y0,
        !           589:                                        radius,
        !           590:                                        curedge->fax->x0, curedge->fax->y0,
        !           591:                                        curedge->fax->radius,
        !           592:                                        &gamma[0], &theta[0],
        !           593:                                        &gamma[1], &theta[1]
        !           594:                                )
        !           595:                        ) {
        !           596:                                if (fabs(x0 - curedge->fax->x0) < EPSILON
        !           597:                                        && fabs(y0 - curedge->fax->y0) < EPSILON
        !           598:                                        && fabs(fabs(radius) - fabs(curedge->fax->radius)) < EPSILON
        !           599:                                ) {
        !           600:                                        curedge->alpha[0] = rprin(curedge->fax->theta1);
        !           601:                                        curedge->alpha[1] = rprin(curedge->fax->theta2);
        !           602:                                        curedge->code[0] = ON0;
        !           603:                                        curedge->code[1] = ON1;
        !           604:                                } else {
        !           605:                                        curedge->code[0] = curedge->code[1] = UNUSED;
        !           606:                                }
        !           607:                        } else if (fabs(theta[0] - theta[1]) < EPSILON) {
        !           608:                                if (fabs(theta[0] - curedge->fax->theta1) < EPSILON)
        !           609:                                        curedge->code[0] = curedge->flipped?AT1:AT0;
        !           610:                                else if (fabs(theta[0] - curedge->fax->theta2) < EPSILON)
        !           611:                                        curedge->code[0] = curedge->flipped?AT0:AT1;
        !           612:                                else
        !           613:                                        curedge->code[0] = TANGENT;
        !           614:                                curedge->alpha[0] = rprin(gamma[0]);
        !           615:                                curedge->code[1] = UNUSED;
        !           616:                        } else {
        !           617:                                for (i = 0; i < 2; i ++) {
        !           618:                                        dprintf "disposition of %f\n", theta[i]);
        !           619:                                        if (curedge->fax->theta2 < 2.0*PI) {
        !           620:                                                if (theta[i] - curedge->fax->theta1 < -EPSILON
        !           621:                                                        || curedge->fax->theta2 - theta[i] < -EPSILON) {
        !           622:                                                        curedge->code[i] = UNUSED;
        !           623:                                                        dprintf "intersection off arc\n");
        !           624:                                                        continue;
        !           625:                                                }
        !           626:                                        }
        !           627:                                        if (curedge->fax->theta2 > 2.0*PI) {
        !           628:                                                if (theta[i] - curedge->fax->theta1 < -EPSILON
        !           629:                                                        && curedge->fax->theta2 - theta[i] < 2.0*PI - EPSILON) {
        !           630:                                                        curedge->code[i] = UNUSED;
        !           631:                                                        dprintf "intersection off arc\n");
        !           632:                                                        continue;
        !           633:                                                }
        !           634:                                        }
        !           635:                                        rem = modf(fabs(theta[i] - curedge->fax->theta1)/(2.0*PI), &dummy);
        !           636:                                        dprintf "rem1 = %f\n", rem);
        !           637:                                        if (rem < EPSILON || fabs(1.0 - rem) < EPSILON) {
        !           638:                                                curedge->alpha[i] = rprin(gamma[i]);
        !           639:                                                curedge->code[i] = curedge->flipped?AT1:AT0;
        !           640:                                                continue;
        !           641:                                        }
        !           642:                                        rem = modf(fabs(theta[i] - curedge->fax->theta2)/(2.0*PI), &dummy);
        !           643:                                        dprintf "rem2 = %f\n", rem);
        !           644:                                        if (rem < EPSILON || fabs(1.0 - rem) < EPSILON) {
        !           645:                                                curedge->alpha[i] = rprin(gamma[i]);
        !           646:                                                curedge->code[i] = curedge->flipped?AT0:AT1;
        !           647:                                                continue;
        !           648:                                        }
        !           649:                                        dprintf "simple\n");
        !           650:                                        curedge->code[i] = SIMPLE;
        !           651:                                        curedge->alpha[i] = rprin(gamma[i]);
        !           652:                                }
        !           653:                        }
        !           654:                } else {
        !           655:                        impossible ("polyarc(D)");
        !           656:                }
        !           657:                curedge = curedge->next;
        !           658:        } while (curedge != edgelist);
        !           659:        if (dbg) {
        !           660:                curedge = edgelist;
        !           661:                do {
        !           662:                        fprintf (stderr, "s (%f,%f); e (%f,%f)\n",
        !           663:                                curedge->sx, curedge->sy,
        !           664:                                curedge->ex, curedge->ey
        !           665:                        );
        !           666:                        fprintf (stderr, "st (%f,%f); et (%f,%f)\n",
        !           667:                                curedge->stx, curedge->sty,
        !           668:                                curedge->etx, curedge->ety
        !           669:                        );
        !           670:                        for (i = 0; i < POSSINTER; i ++)
        !           671:                                fprintf (stderr, "%d %f\n",
        !           672:                                        curedge->code[i],
        !           673:                                        curedge->alpha[i]
        !           674:                                );
        !           675:                        curedge = curedge->next;
        !           676:                } while (curedge != edgelist);
        !           677:        }
        !           678:        prevedge = edgelist;
        !           679:        curedge = edgelist->next;
        !           680:        do {
        !           681:                for (i = 0; i < POSSINTER; i ++) {
        !           682:                        stx = xtanp(x0,y0,radius,curedge->alpha[i]);
        !           683:                        sty = ytanp(x0,y0,radius,curedge->alpha[i]);
        !           684:                        etx = xtane(x0,y0,radius,curedge->alpha[i]);
        !           685:                        ety = ytane(x0,y0,radius,curedge->alpha[i]);
        !           686:                        switch (curedge->code[i]) {
        !           687:                        case UNUSED:
        !           688:                                break;
        !           689:                        case SIMPLE:
        !           690:                                opqinsert(SIMPLE, curedge->alpha[i], &alphalist);
        !           691:                                break;
        !           692:                        case AT0:
        !           693:                                dprintf "AT0\n");
        !           694:                                if (ccross(x0,y0,radius,
        !           695:                                        curedge->sx, curedge->sy,
        !           696:                                        curedge->ex, curedge->ey,
        !           697:                                        curedge->stx, curedge->sty,
        !           698:                                        prevedge->ex, prevedge->ey,
        !           699:                                        prevedge->sx, prevedge->sy,
        !           700:                                        prevedge->etx, prevedge->ety
        !           701:                                ))
        !           702:                                        opqinsert(SIMPLE, curedge->alpha[i], &alphalist);
        !           703:                                else
        !           704:                                        opqinsert(IGNORE, curedge->alpha[i], &alphalist);
        !           705:                                break;
        !           706:                        case AT1:
        !           707:                                /* should be taken care of by next AT0 */
        !           708:                                break;
        !           709:                        case ON0:
        !           710:                        case ON1:
        !           711:                                dprintf "ON\n");
        !           712:                                if (ccross(x0,y0,radius,
        !           713:                                        prevedge->ex, prevedge->ey,
        !           714:                                        prevedge->sx, prevedge->sy,
        !           715:                                        prevedge->etx, prevedge->ety,
        !           716:                                        curedge->next->sx, curedge->next->sy,
        !           717:                                        curedge->next->ex, curedge->next->ey,
        !           718:                                        curedge->next->stx, curedge->next->sty
        !           719:                                ))
        !           720:                                        opqinsert((curedge->code[i] == ON0)?INFL0:INFL1, curedge->alpha[i], &alphalist);
        !           721:                                else
        !           722:                                        opqinsert((curedge->code[i] == ON0)?EXT0:EXT1, curedge->alpha[i], &alphalist);
        !           723:                                break;
        !           724:                        case TANGENT:
        !           725:                                opqinsert(IGNORE, curedge->alpha[i], &alphalist);
        !           726:                                break;
        !           727:                        default:
        !           728:                                impossible ("polyline(B)");
        !           729:                                break;
        !           730:                        }
        !           731:                }
        !           732:                prevedge = curedge;
        !           733:                curedge = curedge->next;
        !           734:        } while (prevedge != edgelist);
        !           735:        opqinsert(INHERIT, rprin(startang), &alphalist);
        !           736:        opqinsert(INHERIT, rprin(endang), &alphalist);
        !           737:        if (dbg) {
        !           738:                fprintf (stderr, "interalpha:\n");
        !           739:                for (interwalk = alphalist;
        !           740:                        interwalk;
        !           741:                        interwalk = interwalk->next)
        !           742:                        fprintf (stderr, "%d %f, ", interwalk->code, interwalk->alpha);
        !           743:                fprintf (stderr, "\n");
        !           744:        }
        !           745:        ((OPQPTR) tail((NAMEPTR) alphalist))->next = alphalist;
        !           746:        interwalk = alphalist;
        !           747:        onedge = FALSE;
        !           748:        do {
        !           749:                switch (interwalk->code) {
        !           750:                case EXT0:
        !           751:                        alpha[0] = interwalk->alpha;
        !           752:                        onedge = TRUE;
        !           753:                        break;
        !           754:                case EXT1:
        !           755:                        alpha[1] = interwalk->alpha;
        !           756:                        onedge = TRUE;
        !           757:                        break;
        !           758:                case INFL0:
        !           759:                        alpha[0] = interwalk->alpha;
        !           760:                        onedge = TRUE;
        !           761:                        break;
        !           762:                case INFL1:
        !           763:                        alpha[1] = interwalk->alpha;
        !           764:                        onedge = TRUE;
        !           765:                        break;
        !           766:                default:
        !           767:                        break;
        !           768:                }
        !           769:                interwalk = interwalk->next;
        !           770:        } while (interwalk != alphalist);
        !           771:        if (onedge) {
        !           772:                rem = modf(fabs(alpha[0]-alpha[1])/(2.0*PI), &dummy);
        !           773:                if (rem < EPSILON || fabs(1.0-rem) < EPSILON)
        !           774:                        return;
        !           775:        }
        !           776:        interwalk = alphalist;
        !           777:        do {
        !           778:                if (interwalk->code == EXT0 || interwalk->code == INFL0 || interwalk->code == INHERIT)
        !           779:                        interwalk = interwalk->next;
        !           780:                else
        !           781:                        break;
        !           782:        } while (interwalk != alphalist);
        !           783:        rem = modf(fabs(interwalk->alpha - interwalk->next->alpha)/(2.0*PI), &dummy);
        !           784:        if (rem < EPSILON || fabs(1.0-rem) < EPSILON)
        !           785:                interwalk = interwalk->next;
        !           786:        inside = ptinpoly (
        !           787:                edgelist,
        !           788:                x0 + fabs(radius)*cos((interwalk->alpha + interwalk->next->alpha)/2.0),
        !           789:                y0 + fabs(radius)*sin((interwalk->alpha + interwalk->next->alpha)/2.0)
        !           790:        );
        !           791:        dprintf "inside: %d\n", inside);
        !           792:        alphalist = interwalk->next;
        !           793:        interwalk = alphalist;
        !           794:        onedge = FALSE;
        !           795:        do {
        !           796:                switch (interwalk->code) {
        !           797:                case SIMPLE:
        !           798:                        interwalk->code = (!inside)?INBEGIN:OUTBEGIN;
        !           799:                        inside = !inside;
        !           800:                        break;
        !           801:                case EXT1:
        !           802:                        interwalk->code = inside?INBEGIN:OUTBEGIN;
        !           803:                        onedge = FALSE;
        !           804:                        break;
        !           805:                case EXT0:
        !           806:                        interwalk->code = ONBEGIN;
        !           807:                        onedge = TRUE;
        !           808:                        break;
        !           809:                case INFL1:
        !           810:                        interwalk->code = (!inside)?INBEGIN:OUTBEGIN;
        !           811:                        inside = !inside;
        !           812:                        onedge = FALSE;
        !           813:                        break;
        !           814:                case INFL0:
        !           815:                        interwalk->code = ONBEGIN;
        !           816:                        onedge = TRUE;
        !           817:                        break;
        !           818:                case INHERIT:
        !           819:                case IGNORE:
        !           820:                        interwalk->code = onedge?ONBEGIN:(inside?INBEGIN:OUTBEGIN);
        !           821:                        break;
        !           822:                default:
        !           823:                        impossible("polyline(C)");
        !           824:                        break;
        !           825:                }
        !           826:                interwalk = interwalk->next;
        !           827:        } while (interwalk != alphalist);
        !           828:        while (alphalist->alpha < alphalist->next->alpha)
        !           829:                alphalist = alphalist->next;
        !           830:        alphalist = alphalist->next;
        !           831:        if (dbg) {
        !           832:                fprintf (stderr, "interalpha:\n");
        !           833:                interwalk = alphalist;
        !           834:                do {
        !           835:                        fprintf (stderr, "%d %f, ", interwalk->code, interwalk->alpha);
        !           836:                        interwalk = interwalk->next;
        !           837:                } while (interwalk != alphalist);
        !           838:                fprintf (stderr, "\n");
        !           839:        }
        !           840:        interwalk = alphalist;
        !           841:        do {
        !           842:                if (interwalk->alpha > interwalk->next->alpha)
        !           843:                        break;
        !           844:                if (endang < 2.0*PI + EPSILON) {
        !           845:                        if (interwalk->alpha < startang - EPSILON || interwalk->alpha > endang + EPSILON) {
        !           846:                                dprintf "arc rejected (A)\n");
        !           847:                                interwalk = interwalk->next;
        !           848:                                continue;
        !           849:                        }
        !           850:                        if (interwalk->next->alpha < startang - EPSILON || interwalk->next->alpha > endang + EPSILON) {
        !           851:                                dprintf "arc rejected (B)\n");
        !           852:                                interwalk = interwalk->next;
        !           853:                                continue;
        !           854:                        }
        !           855:                } else {
        !           856:                        if (interwalk->alpha < startang - EPSILON && interwalk->alpha > endang + EPSILON - 2.0*PI) {
        !           857:                                dprintf "arc rejected (C)\n");
        !           858:                                interwalk = interwalk->next;
        !           859:                                continue;
        !           860:                        }
        !           861:                        if (interwalk->next->alpha < startang - EPSILON && interwalk->next->alpha > endang + EPSILON - 2.0*PI) {
        !           862:                                dprintf "arc rejected (D)\n");
        !           863:                                interwalk = interwalk->next;
        !           864:                                continue;
        !           865:                        }
        !           866:                }
        !           867:                linewalk = angularc (
        !           868:                        x0, y0,
        !           869:                        radius,
        !           870:                        interwalk->alpha,
        !           871:                        interwalk->next->alpha
        !           872:                );
        !           873:                switch (interwalk->code) {
        !           874:                case INBEGIN:
        !           875:                        inwalk->next = linewalk;
        !           876:                        inwalk = inwalk->next;
        !           877:                        break;
        !           878:                case OUTBEGIN:
        !           879:                        outwalk->next = linewalk;       
        !           880:                        outwalk = outwalk->next;
        !           881:                        break;
        !           882:                case ONBEGIN:
        !           883:                        tryfree(linewalk);
        !           884:                        break;
        !           885:                default:
        !           886:                        impossible("polyline(D)");
        !           887:                        break;
        !           888:                }
        !           889:                interwalk = interwalk->next;
        !           890:        } while (interwalk != alphalist);
        !           891:        *inlines = nuin.next;
        !           892:        *outlines = nuout.next;
        !           893:        *both = NULL;
        !           894: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.