break_wires_at_point(): oblique lines can be cut at any point, the break point will be aligned to the snap value and broken wires are slightly changed to land on this new point.
This commit is contained in:
parent
f0c83e72b4
commit
5181ca77e6
50
src/check.c
50
src/check.c
|
|
@ -398,19 +398,61 @@ static int touches_inst_pin(double x, double y, int inst)
|
|||
return touches;
|
||||
}
|
||||
|
||||
/* return 2 if x0, y0 is on the segment
|
||||
* return 1 if x0, y0 is less than cadsnap (10) from the segment
|
||||
* In this case x0, y0 are reset to the closest point on the segment */
|
||||
static int closest_point_calculation(double x1, double y1, double x2, double y2, double *x0, double *y0)
|
||||
{
|
||||
double projection, sq_distance, x3, y3;
|
||||
double cs = tclgetdoublevar("cadsnap"), sq_cs;
|
||||
int ret = 0;
|
||||
|
||||
sq_cs = cs * cs; /* get squared value to compare with squared distance */
|
||||
|
||||
if(x1 == x2 && y1 == y2) {
|
||||
x3 = x1;
|
||||
y3 = y1;
|
||||
} else {
|
||||
projection = (x2 - x1) * (*x0 - x1) + (y2 - y1) * (*y0 - y1);
|
||||
projection /= (x2 - x1) * ( x2 - x1) + (y2 - y1) * (y2 - y1);
|
||||
x3 = x1 + projection * (x2 - x1);
|
||||
y3 = y1 + projection * (y2 - y1);
|
||||
}
|
||||
sq_distance = (*x0 - x3) * (*x0 - x3) + (*y0 - y3) * (*y0 - y3);
|
||||
|
||||
if(x3 >= x1 && x3 <= x2) { /* point is within x1,y1 - x2,y2 */
|
||||
if(sq_distance == 0) ret = 2;
|
||||
else if(sq_distance < sq_cs) ret = 1;
|
||||
}
|
||||
|
||||
dbg(0, "x3 = %g y3=%g dist=%g ret=%d\n", x3, y3, sqrt(sq_distance), ret);
|
||||
if(touch(x1, y1, x2, y2, x3, y3)) dbg(0, "touches\n");
|
||||
if(ret == 1) {
|
||||
*x0 = my_round(x3 / cs) * cs;
|
||||
*y0 = my_round(y3 / cs) * cs;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void break_wires_at_point(double x0, double y0)
|
||||
{
|
||||
int i, sqx, sqy;
|
||||
int r, i, sqx, sqy;
|
||||
Wireentry *wptr;
|
||||
int changed=0;
|
||||
double x1, y1, x2, y2;
|
||||
|
||||
dbg(1, "break_wires_at_pins(): processing pin %g %g\n", x0, y0);
|
||||
get_square(x0, y0, &sqx, &sqy);
|
||||
for(wptr=xctx->wire_spatial_table[sqx][sqy]; wptr; wptr=wptr->next) {
|
||||
i = wptr->n;
|
||||
if( touch(xctx->wire[i].x1, xctx->wire[i].y1, xctx->wire[i].x2, xctx->wire[i].y2, x0,y0) ) {
|
||||
if( (x0!=xctx->wire[i].x1 && x0!=xctx->wire[i].x2) ||
|
||||
(y0!=xctx->wire[i].y1 && y0!=xctx->wire[i].y2) ) {
|
||||
x1 = xctx->wire[i].x1;
|
||||
y1 = xctx->wire[i].y1;
|
||||
x2 = xctx->wire[i].x2;
|
||||
y2 = xctx->wire[i].y2;
|
||||
r = closest_point_calculation(x1, y1, x2, y2, &x0, &y0);
|
||||
if( r == 1 || touch(x1, y1, x2, y2, x0,y0) ) {
|
||||
if( (x0 != x1 && x0 != x2) ||
|
||||
(y0 != y1 && y0 != y2) ) {
|
||||
dbg(1, "break_wires_at_point(): processing wire %d: %g %g %g %g\n",
|
||||
i, xctx->wire[i].x1, xctx->wire[i].y1, xctx->wire[i].x2, xctx->wire[i].y2);
|
||||
if(!changed) { xctx->push_undo(); changed=1;}
|
||||
|
|
|
|||
|
|
@ -349,6 +349,7 @@ extern char win_temp_dir[PATH_MAX];
|
|||
#define CLIP(x,a,b) (((x) < (a)) ? (a) : ((x) > (b)) ? (b) : (x))
|
||||
|
||||
#define MINOR(a,b) ( (a) <= (b) ? (a) : (b) )
|
||||
#define MAJOR(a,b) ( (a) >= (b) ? (a) : (b) )
|
||||
|
||||
/* "show_label" type symbols are used for any type of symbol that
|
||||
* must be automatically highlighted by attached nets
|
||||
|
|
|
|||
Loading…
Reference in New Issue