Index: trunk/src/libgrbs/collision.c =================================================================== --- trunk/src/libgrbs/collision.c (revision 1331) +++ trunk/src/libgrbs/collision.c (revision 1332) @@ -26,6 +26,13 @@ return NULL; } +static grbs_2net_t *coll_check_line(grbs_t *grbs, grbs_2net_t *tn, double x1, double y1, double x2, double y2) +{ +#warning TODO: callback: use ->new_* if exist or plain fields + + return NULL; +} + static void coll_report(grbs_t *grbs, grbs_2net_t *tn, grbs_2net_t *coll_tn, grbs_arc_t *coll_arc) { if ((grbs->coll_report_cb != NULL) && (coll_tn != NULL)) Index: trunk/src/libgrbs/route_common.c =================================================================== --- trunk/src/libgrbs/route_common.c (revision 1331) +++ trunk/src/libgrbs/route_common.c (revision 1332) @@ -11,14 +11,41 @@ static const int shrink_concave = 0; /* Calculate the radius of a new orbit (arc->new_r) around addr for tn */ +static double grbs_get_new_radius_(grbs_t *grbs, grbs_2net_t *tn, grbs_arc_t *arc) +{ + return arc->r + arc->copper + tn->copper + GRBS_MAX(arc->clearance, tn->clearance); +} + static double grbs_get_new_radius(grbs_t *grbs, grbs_2net_t *tn, grbs_addr_t *addr) { - grbs_arc_t *arc = addr->obj.arc; + assert((addr->type & ADDR_ARC_CONVEX) || (addr->type & ADDR_ARC_CONCAVE)); + assert((addr->type & 0xF0) != 0); + return grbs_get_new_radius_(grbs, tn, addr->obj.arc); +} + +static void grbs_get_arc_end_(grbs_t *grbs, grbs_2net_t *tn, grbs_arc_t *arc, int which, double *ex, double *ey) +{ + double ang, r; + + assert((which == 0) || (which == 1)); + + ang = arc->new_sa; + if (which == 1) + ang += arc->new_da; + + r = grbs_get_new_radius_(grbs, tn, arc); + + *ex = arc->parent_pt->x + cos(ang) * r; + *ey = arc->parent_pt->y + sin(ang) * r; +} + +static void grbs_get_new_arc_end(grbs_t *grbs, grbs_2net_t *tn, grbs_addr_t *addr, int which, double *ex, double *ey) +{ assert((addr->type & ADDR_ARC_CONVEX) || (addr->type & ADDR_ARC_CONCAVE)); assert((addr->type & 0xF0) != 0); - return arc->r + arc->copper + tn->copper + GRBS_MAX(arc->clearance, tn->clearance); + grbs_get_arc_end_(grbs, tn, addr->obj.arc, which, ex, ey); } /* Return if ang is a valid entry/exit point between two existing arcs Index: trunk/src/libgrbs/route_next.c =================================================================== --- trunk/src/libgrbs/route_next.c (revision 1331) +++ trunk/src/libgrbs/route_next.c (revision 1332) @@ -69,6 +69,7 @@ { grbs_point_t *from_pt = addr_point(from); grbs_2net_t *coll_tn; + double aex, aey; if (new_at_from) { /* when creating a new go-around arc, we first place start (new_sa), so @@ -98,7 +99,15 @@ failprintf("tune4exit failed\n"); return NULL; } -#warning TODO: line coll + + grbs_get_new_arc_end(grbs, tn, from, 1, &aex, &aey); + coll_tn = coll_check_line(grbs, tn, aex, aey, to_pt->x, to_pt->y); + if (coll_tn != NULL) { + failprintf("line collision\n"); + coll_report_tn(grbs, tn, coll_tn); + return NULL; + } + return grbs_addr_new(grbs, ADDR_POINT, to_pt); } @@ -107,6 +116,7 @@ grbs_point_t *from_pt = addr_point(from), *to_pt; grbs_arc_t *to_arc; grbs_2net_t *coll_tn; + double ex1, ey1, ex2, ey2; assert((from->type & ADDR_ARC_CONVEX) || (from->type & ADDR_ARC_CONCAVE)); assert(from->type & ADDR_ARC_END); @@ -135,7 +145,15 @@ return NULL; } -#warning TODO: line coll + grbs_get_new_arc_end(grbs, tn, from, 1, &ex1, &ey1); + grbs_get_arc_end_(grbs, tn, to_arc, 0, &ex2, &ey2); + coll_tn = coll_check_line(grbs, tn, ex1, ey1, ex2, ey2); + if (coll_tn != NULL) { + failprintf("line collision\n"); + coll_report_tn(grbs, tn, coll_tn); + to_arc->new_in_use = 0; + return NULL; + } return grbs_addr_new(grbs, (to->type & 0x0F) | ADDR_ARC_END, to_arc); } @@ -309,6 +327,7 @@ static grbs_addr_t *path_find_inc2inc(grbs_t *grbs, grbs_2net_t *tn, grbs_addr_t *from, grbs_point_t *to_pt) { + grbs_2net_t *coll_tn; grbs_arc_t *coll; grbs_point_t *from_pt = addr_point(from); double vx = to_pt->x - from_pt->x, vy = to_pt->y - from_pt->y; @@ -325,7 +344,12 @@ return NULL; } -#warning TODO: line coll + coll_tn = coll_check_line(grbs, tn, from_pt->x, from_pt->y, to_pt->x, to_pt->y); + if (coll_tn != NULL) { + failprintf("line collision\n"); + coll_report_tn(grbs, tn, coll_tn); + return NULL; + } return grbs_addr_new(grbs, ADDR_POINT, to_pt); }