Crossing two paths in canvas using Android

I add 49 Rects to my canvas and also keep the area for each Rect in an ArrayList:

private void addCoordinates(){
    if (regions.size() > 0) {
        regions.clear();
    }
    Paint xpaint = new Paint();
    xpaint.setColor(Color.LTGRAY);
    xpaint.setStyle(Paint.Style.STROKE);
    xpaint.setStrokeWidth(10);
    for (int j=1;j<8;j++){
        for (int i=1;i<8;i++){
            Region reg = new Region();
            Path p = new Path();
            RectF rect = new RectF();
            rect.set(0, Calculations.convertscale(scale,(float) 91.43 * i), Calculations.convertscale(scale,(float) 91.43 * j), 0);
            canvas.drawRect(rect, xpaint);          
            p.computeBounds(rect, true);
            reg.setPath(p, new Region((int) rect.left, (int) rect.top, (int) rect.right, (int) rect.bottom)); 
            regions.add(reg);
        }
    }
}

      

Then I draw an intersecting area among the four circles, clipping the path of each circle:

 private void interSection(){

    canvas.clipPath(pathA, Region.Op.INTERSECT);
    canvas.clipPath(pathB, Region.Op.INTERSECT);  
    canvas.clipPath(pathC, Region.Op.INTERSECT);
    canvas.clipPath(pathD, Region.Op.INTERSECT);

    canvas.drawPath(pathA, mPaint);
    canvas.drawPath(pathB, mPaint);
    canvas.drawPath(pathC, mPaint);
    canvas.drawPath(pathD, mPaint);       

    drawingImageView.invalidate();
}

      

My task is to find out which of these 49 Rect actually intersects the drawing area, as shown in the screenshot below:

enter image description here

I tried with the code block below, but it gives me all 49 Rect instead of 9 as expected. How do I identify the edges that intersect with the red area ?.

private void checkRectangles() {
    int size = regions.size();
    for (Region reg:regions){
        Path path = reg.getBoundaryPath();
        if (path.op(path, pathA, Path.Op.INTERSECT)){
            count++;
        }
    }
}

      

+3


source to share


1 answer


It looks like you are defining your rectangles so that they all overlap, and your first few rectangles could be vertical lines with a width of 0. Something like the following should work:

RectF rects[][] = new RectF[rows][columns]; // rows & columns are global vars
//(next part goes in your addCoordinates)
for (int i=0; i<rows, i++) {
    for (int j=0; j<columns, j++) {
        canvas.drawRect(rects[i][j], paint);
    }
}
//(next part I wrote as a separate method; could be more useful that way)
private void setupRects(float scale) {
    for (int j=0; j<rows, j++) {
        for (int i=0; i<columns, i++) {
            //note: I usually index from 0 to length instead of from 1 to length+1
            rects[i][j] = new RectF(i*scale,j*scale,(i+1)*scale,(j+1)*scale);
        }
    }
}
/* Example output, with scale of 1:
 * rects[0][0] goes from (0,0) to (1,1)
 * rects[0][1] goes from (1,0) to (2,1)
 * rects[7][7] goes from (7,7) to (8,8)
 */

      

I haven't used the intersect function before, but it seems to "worked" with your previous rectangle definition, so it should "work as intended" with the proposed changes.

For simplicity, my algorithm creates rectangles that touch each other. To realize your distance, you can either change the equations or just overlay a bunch of lines.

If this is helpful, you might consider making the equation more robust:



RectF(X0+i*scale,Y0+j*scale,X0+(i+1)*scale,Y0+(j+1)*scale);

      

Beforehand, you can define X0 = 0 and Y0 = 0 and increase or decrease them to shift the entire collection of rectangles.

For fun, you can try creating your own intersection algorithm. With some work, you can find equations for the sections of the curve. For simplicity, you can reduce each rectangle to five points (corner points + center point), and then check if any point is in the curve equations. If so, then you have an intersection!

Actually, now that I think about it, you can forget about drawing rectangles and just overlay lines, which will look like a bunch of rectangles. Whether you are doing this or not depends on your overall goals. In this case, you should check which lines are crossing the shape and then interpret the results correctly.

+1


source







All Articles