Naddy
Naddy

Reputation: 2674

Android-Optimize line drawing with Canvas

I am drawing a hexagonal grid on my entire phone's screen. I am drawing a hexagon by drawing six lines using Canvas. Too many lines are being drawn which makes the app unresponsive. I had to do android:HardwareAccelerated=false to atleast make it work on my Nexus 4 otherwise the app crashed with this error :

06-22 14:11:46.664: A/libc(5743): Fatal signal 6 (SIGABRT) at 0x0000166f (code=-6), thread 5743 (.nadeem.sensus4)

Although the app doesn't crash now, it takes too much time to draw the grid. This is the code of my CustomView which draws the grid :

public DrawView(Context context, Hexagon hex) {
    super(context);
    this.context = context;
    setLayerType(View.LAYER_TYPE_HARDWARE, null);
     this.hex = hex;

}

@Override
public void onDraw(Canvas canvas) {

    double xOff = Math.cos(Math.PI / 6) * hex.radius;//radius is 12 for now
    double yOff = Math.sin(Math.PI / 6) * hex.radius; // third of the hex
                                                        // height

    for (int i = 0; i < 60; ++i) {
        for (int j = 0; j < 40; ++j) {
            double xPos = j * xOff * 2;

            if (i % 2 != 0) { // if the current line is not even
                xPos += xOff; // extra offset of half the width on x axis
            }


            double yPos = i * yOff * 3;
            createHexagon(xPos, // X pos for hexagon center on the scene
                    yPos, canvas);
        }

    }

}

public void createHexagon(double x, double y, Canvas canvas) {

    paint.setColor(Color.BLACK);
    paint.setStyle(Style.STROKE);

    // paint.setStyle(Style.FILL);
    for (int i = 0; i < 6; i++) {
        double angle = 2 * Math.PI / 6 * (i + 0.5);


        double x_i = x + hex.radius * Math.cos(angle);
        double y_i = y + hex.radius * Math.sin(angle);
        if (i == 0)
            wallpath.moveTo((float) x_i, (float) y_i);
        else
            wallpath.lineTo((float) x_i, (float) y_i);
    }
    canvas.drawPath(wallpath, paint);
    canvas = null;
}

I want to ask if there's way to increase the performance or any other alternate way to achieve this grid.

Upvotes: 0

Views: 660

Answers (2)

Steven
Steven

Reputation: 177

You can achieve the same effect by drawing straight lines and utilizing DashPathEffect to toggle a line from your background colour to your visible colour.

enter image description here

Where the faint lines don't belong is where that particular line segment would be turned off. Since the pattern is predictable, so is your stroke effect. Because you said in a comment that you also need the coordinates of all the vertices, run a separate loop that calculates from a starting point and propagate your vertices list from there.

Upvotes: 0

Gabe Sechan
Gabe Sechan

Reputation: 93542

Do your drawing in layers. The first time you draw, draw all your hexagons to a single bitmap. Then in all future draws, just draw that bitmap to the screen. Then add in whatever else you need to draw on top of that. It will save you 14000 draw line commands.

Your other good option is to move to openGL for drawing. But there is no way you'll ever get 14K lines to draw without hardware acceleration with any real speed.

Upvotes: 1

Related Questions