+ for( int i=0; i<sz; ++i ) {
+ TracerPoint *pt = points[i];
+ float px = pt->x - output_x, py = pt->y - output_y;
+ float nx = shift_down ? px*s : px*ct + py*st;
+ float ny = shift_down ? py*s : py*ct - px*st;
+ point_list->set_point(i, PT_X, pt->x = nx + output_x);
+ point_list->set_point(i, PT_Y, pt->y = ny + output_y);
+ }
+ point_list->update(-1);
+ button_no = 0;
+ break; }
+ case RIGHT_BUTTON: {
+ // shift_down adds to end
+ int sz = !shift_down ? points.size() : 0;
+ int k = !shift_down ? -1 : points.size()-1;
+ float mx = FLT_MAX;
+ for( int i=0; i<sz; ++i ) {
+ // pt on line pt[i+0]..pt[i+1] nearest cx,cy
+ TracerPoint *pt0 = points[i+0];
+ TracerPoint *pt1 = i+1<sz ? points[i+1] : points[0];
+ float x0 = pt0->x, y0 = pt0->y;
+ float x1 = pt1->x, y1 = pt1->y;
+ float dx = x1-x0, dy = y1-y0;
+ float rr = dx*dx + dy*dy;
+ if( !rr ) continue;
+ float u = ((x1-output_x)*dx + (y1-output_y)*dy) / rr;
+ if( u < 0 || u > 1 ) continue; // past endpts
+ float x = x0*u + x1*(1-u);
+ float y = y0*u + y1*(1-u);
+ dx = output_x-x; dy = output_y-y;
+ float dd = dx*dx + dy*dy; // d**2 closest approach
+ if( mx > dd ) { mx = dd; k = i; }
+ }
+ TracerPoint *pt = points[sz=plugin->new_point()];
+ int hot_point = k+1;
+ for( int i=sz; i>hot_point; --i ) points[i] = points[i-1];
+ points[hot_point] = pt;
+ pt->x = output_x; pt->y = output_y;
+ point_list->update(hot_point);
+ break; }
+ case LEFT_BUTTON: {
+ int hot_point = -1, sz = points.size();
+ if( sz > 0 ) {