0

I want to detect a line intersection using Android.graphics.Path. Right now, it seems that the intersection is always empty, even though the lines should intersect. To reproduce this, I created this simplifed code that is running within my Activity's onCreate() Method:

Path leftToRight = new Path();
leftToRight.moveTo(0,0);
leftToRight.lineTo(200,200);

Path rightToLeft = new Path();
rightToLeft.moveTo(200,0);
rightToLeft.lineTo(0,200);

Path resultPath = new Path();

if (resultPath.op(rightToLeft, leftToRight, Path.Op.INTERSECT)) {
    if (!resultPath.isEmpty()) {
        Log.d(this.getLocalClassName(), "INTERSECTION DETECTED");
    } else {
        Log.d(this.getLocalClassName(), "NO INTERSECTION DETECTED");
    }
}

The log output says 'NO INTERSECTION DETECTED'. I already read many answers around this topic on StackOverflow, like here, but using Region.op is not an option in my case, as my tests showed that it will create a rectangle around the path before intersecting.

Some sources indicate that intersect might only properly work for Path objects that have a closed bound, like a square or a rectangle. But I can hardly imagine that Google would not implement basic line intersection. What am I missing here?

So I am thankful for a plain answer, whether it is possible to intersect Paths that just contain lines in Android using this method, or not.

BenjyTec
  • 1,719
  • 2
  • 12
  • 22
  • I think there is a typo on your code..."leftToRight.moveTo(200,0);" refers to previous Path object and not the second one. – emandt Apr 15 '21 at 12:10
  • @emandt You're right, thanks, edited my post. Tried again with the corrected code, but still, the problem persists. – BenjyTec Apr 15 '21 at 13:57
  • 1
    Op.INTERSECT, or more in general OP, works only on Closed paths – emandt Apr 15 '21 at 14:54

1 Answers1

0

After some time trying around, I found that the method myPaint.getFillType(Path src, Path dst) does the trick. What it actually does is it takes the Path src and will apply myPaint to it and store the result in dst. After the operation, Path dst drawn without any specific Paint will look the same as Path src drawn with myPaint.

As a side effect of this, dst will now no longer be a 'hairline' (aka width 0), where no intersection can be detected. It now will be a closed shape with a certain thickness. With that, Op.INTERSECTION does work. The updated code looks like this:

Path leftToRight = new Path();
leftToRight.moveTo(0,0);
leftToRight.lineTo(200,200);

Path rightToLeft = new Path();
rightToLeft.moveTo(200,0);
rightToLeft.lineTo(0,200);

Paint myPaint = new Paint();
myPaint.setStrokeWidth(2f);
myPaint.setStyle(Paint.Style.STROKE);
myPaint.getFillPath(leftToRight, leftToRight);
myPaint.getFillPath(rightToLeft, rightToLeft);

Path resultPath = new Path();

if (resultPath.op(rightToLeft, leftToRight, Path.Op.INTERSECT)) {
    if (!resultPath.isEmpty()) {
        Log.e(this.getLocalClassName(), "INTERSECTION DETECTED :)");
    } else {
        Log.e(this.getLocalClassName(), "NO INTERSECTION DETECTED :(");
    }
}

Note that setStrokeWidth() obviously needs to be set to a value > 0.

BenjyTec
  • 1,719
  • 2
  • 12
  • 22