1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
|
/* libgrbs - geometric rubber band sketch model
Copyright (C) 2021 Tibor 'Igor2' Palinkas
(Supported by NLnet NGI0 PET Fund in 2021)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Contact:
Project page: http://repo.hu/projects/libgrbs
lead developer: http://repo.hu/projects/pcb-rnd/contact.html
*/
void grbs_point_reg(grbs_t *grbs, grbs_point_t *p)
{
double r = p->copper + p->clearance;
p->bbox.x1 = p->x - r; p->bbox.y1 = p->y - r;
p->bbox.x2 = p->x + r; p->bbox.y2 = p->y + r;
grbs_rtree_insert(&grbs->point_tree, p, &p->bbox);
}
void grbs_point_unreg(grbs_t *grbs, grbs_point_t *p)
{
grbs_rtree_delete(&grbs->point_tree, p, &p->bbox);
}
/* returns the point an incident line of tn would collide with its endcap
at tpt (or NULL on no collision) */
static grbs_point_t *grbs_endcap_point_collision(grbs_t *grbs, grbs_2net_t *tn, grbs_point_t *tpt)
{
grbs_rtree_box_t bbox;
double bloat = tn->copper + tn->clearance;
grbs_point_t *pt;
grbs_rtree_it_t it;
bbox.x1 = tpt->x - bloat; bbox.y1 = tpt->y - bloat;
bbox.x2 = tpt->x + bloat; bbox.y2 = tpt->y + bloat;
for(pt = grbs_rtree_first(&it, &grbs->point_tree, &bbox); pt != NULL; pt = grbs_rtree_next(&it)) {
double dx = pt->x - tpt->x, dy = pt->y - tpt->y;
double d2 = dx*dx + dy*dy, maxd = tpt->copper + pt->copper + GRBS_MAX(tpt->clearance, pt->clearance);
if (d2 > maxd*maxd)
return pt;
}
return NULL;
}
/* returns the arc an incident line of tn would collide with its endcap
at tpt (or NULL on no collision); arcs going around tpt are ignored */
static grbs_arc_t *grbs_endcap_arc_collision(grbs_t *grbs, grbs_2net_t *tn, grbs_point_t *tpt)
{
grbs_rtree_box_t bbox;
double bloat = tn->copper + tn->clearance;
grbs_arc_t *arc;
grbs_rtree_it_t it;
g2d_carc_t outer;
g2d_vect_t v;
bbox.x1 = tpt->x - bloat; bbox.y1 = tpt->y - bloat;
bbox.x2 = tpt->x + bloat; bbox.y2 = tpt->y + bloat;
v.x = tpt->x; v.y = tpt->y;
for(arc = grbs_rtree_first(&it, &grbs->arc_tree, &bbox); arc != NULL; arc = grbs_rtree_next(&it)) {
double r;
grbs_2net_t *atn;
g2d_sarc_t sarc;
if (arc->parent_pt == tpt) continue;
if (arc->in_use == 0) continue;
atn = grbs_arc_parent_2net(arc);
if (atn == tn) continue;
r = tpt->copper + GRBS_MAX(tpt->clearance, atn->clearance);
sarc.c.c.x = arc->parent_pt->x;
sarc.c.c.y = arc->parent_pt->y;
sarc.c.r = arc->r + atn->copper;
sarc.c.start = arc->sa; sarc.c.delta = arc->da;
sarc.s.width = atn->copper;
g2d_sarc_sides(&sarc, &outer, NULL);
if (g2d_iscp_carc_circle(&outer, v, r, 0, 0))
return arc;
}
return NULL;
}
|