Hi.

I'm having trouble with the selection of links that has their cubic property set to true. If one clicks on the beginning point or end point of the link then it selects fine everytime. But selecting the link by clicking on the line in the middle areas of the link does not always work. Why is this? Am I doing something wrong?
I'm running JGo4.1

Yes, the code in JGoStroke.getSegmentNearPoint isn’t precise for cubic strokes. Here’s some replacement code that you can try.

First, remove the following line from getSegmentNearPoint:
line_width *= Math.max(1, Math.max(rect.width, rect.height)/100);
Then substitute the following methods:
static boolean LineContainsPoint(int ax, int ay, int bx, int by, int fuzz, Point p) {
return LineContainsPoint(ax, ay, bx, by, fuzz, p.x, p.y);
}
static boolean LineContainsPoint(int ax, int ay, int bx, int by, int fuzz, int px, int py) {
int maxx, minx, maxy, miny;
if (ax < bx) {
minx = ax;
maxx = bx;
} else {
minx = bx;
maxx = ax;
}
if (ay < by) {
miny = ay;
maxy = by;
} else {
miny = by;
maxy = ay;
}
// do simple vertical and horizontal cases first, without fuzz beyond the endpoints
if (ax == bx && ax-fuzz <= px && px <= ax+fuzz && miny <= py && py <= maxy) return true;
if (ay == by && ay-fuzz <= py && py <= ay+fuzz && minx <= px && px <= maxx) return true;
// if we're in the x-range, including fuzz,
int xrange_high = maxx + fuzz;
int xrange_low = minx - fuzz;
if ((xrange_low <= px) && (px <= xrange_high)) {
// and if we're in the y-range
int yrange_high = maxy + fuzz;
int yrange_low = miny - fuzz;
if ((yrange_low <= py) && (py <= yrange_high)) {
// see if we should compute the X coordinate or Y coordinate
if (xrange_high - xrange_low > yrange_high - yrange_low) {
if (Math.abs(ax - bx) > fuzz) {
double slope = (double)(by - ay) / (double)(bx - ax);
double guess_y = (slope * (px - ax) + ay);
if ((guess_y - fuzz <= py) && (py <= guess_y + fuzz)) {
return true;
}
} else {
return true;
}
} else {
if (Math.abs(ay - by) > fuzz) {
double slope = (double)(bx - ax) / (double)(by - ay);
double guess_x = (slope * (py - ay) + ax);
if ((guess_x - fuzz <= px) && (px <= guess_x + fuzz)) {
return true;
}
} else {
return true;
}
}
}
}
return false;
}
static boolean BezierContainsPoint(int b0x, int b0y, int b1x, int b1y, int b2x, int b2y, int b3x, int b3y, int fuzz, Point p) {
if (!LineContainsPoint(b0x, b0y, b3x, b3y, fuzz, b1x, b1y) || !LineContainsPoint(b0x, b0y, b3x, b3y, fuzz, b2x, b2y)) {
int a1x = (b0x+b1x)/2;
int a1y = (b0y+b1y)/2;
int a2x = (b1x+b2x)/2;
int a2y = (b1y+b2y)/2;
int a3x = (b2x+b3x)/2;
int a3y = (b2y+b3y)/2;
int vx = (a1x+a2x)/2;
int vy = (a1y+a2y)/2;
int wx = (a2x+a3x)/2;
int wy = (a2y+a3y)/2;
int mx = (vx+wx)/2;
int my = (vy+wy)/2;
return BezierContainsPoint(b0x, b0y, a1x, a1y, vx, vy, mx, my, fuzz, p) || BezierContainsPoint(mx, my, wx, wy, a3x, a3y, b3x, b3y, fuzz, p);
} else {
return LineContainsPoint(b0x, b0y, b3x, b3y, fuzz, p.x, p.y);
}
}

Thanks for the code snippet I will put that into action ans see how it performs.