java - How to create jigsaw puzzle pieces using openGL and bezier curve? -
i trying create jigsaw puzzle demo, , know of alternative ways of creating puzzle pieces without using mask. have jigsaw pieces taking full image, breaking image 4 pieces (lets puzzle 2x2) , storing , applying mask each piece. looks below
// create standard puzzle pieces arrypieceendpos = new int[mcols][mrows]; arrypieceimg = new bitmap[mcols * mrows]; arryispiecelocked = new boolean[mcols * mrows]; int pos = 0; (int c = 0; c < mcols; c++) { (int r = 0; r < mrows; r++) { arrypieceimg[pos] = bitmap.createbitmap(mbitmap, c * mpiecewidth, r * mpieceheight, mpiecewidth, mpieceheight); arryispiecelocked[pos] = false; arrypieceendpos[c][r] = pos; pos++; } }
i use helper method apply mask each piece
private bitmap maskmethod(bitmap bmporiginal, bitmap bmpmask) { // adjust mask bitmap if size not size of puzzle piece if (bmpmask.getheight() != mpieceheight || bmpmask.getwidth() != mpiecewidth) { log.e("test", "resize error :: h (mask): " + bmpmask.getheight() + " // w (mask): " + bmpmask.getwidth()); log.d("test", "resize error :: h (norm): " + mpieceheight + " // w (norm): " + mpiecewidth); } canvas canvas = new canvas(); bitmap combine = bitmap.createbitmap(bmporiginal.getwidth(), bmporiginal.getheight(), bitmap.config.argb_8888); canvas.setbitmap(combine); paint paint = new paint(); paint.setfilterbitmap(false); canvas.drawbitmap(bmporiginal, 0, 0, paint); paint.setxfermode(new porterduffxfermode(porterduff.mode.dst_in)); canvas.drawbitmap(bmpmask, 0, 0, paint); paint.setxfermode(null); return combine; }
i have been reading on bezier curves , opengl. neither of these familiar , complex. forming jigsaw puzzle piece, can have example of how can done.
bezier curves can complex, can "cheat" defining puzzle heads using catmul-rom curves first (which have nice property of passing through control points) , trivially converting them bezier curves instead (since they're both plain hermite splines).
so: let's this. example image:
all we've done split far, using simple rules. in sort-of-code (technically: processing):
int hx = width/4; int hy = height/4; for(int x = hx; x<width; x+=hx) { line(x,0,x,height); for(int y = hy; y<height; y+=hy) { line(0,y,width,y); } }
and other fun image, it's not exciting, let's invent puzzle joins. first off, mark centers of cuts:
again not exciting:
for(int x = hx/2; x<width; x+=hx) { for(int y = hy/2; y<height; y+=hy) { ellipse(x + hx/2,y,5,5); ellipse(x,y + hy/2,5,5); } }
but, can make exciting. each of centers, can pick points left/right or up/down (depending on edge) , decide whether have piece extend left or right, , invent points "around center" give our catmull-rom curve:
for(int x = hx/2; x<width; x+=hx) { for(int y = hy/2; y<height; y+=hy) { // horizontal ellipse(x-5, y+hy/2, 2,2); ellipse(x+5, y+hy/2, 2,2); boolean = random(1) < 0.5; if(up) { ellipse(x-random(5,10), y+hy/2 - random(10,20), 2,2); ellipse(x+random(5,10), y+hy/2 - random(10,20), 2,2); } else { ellipse(x-random(5,10), y+hy/2 + random(10,20), 2,2); ellipse(x+random(5,10), y+hy/2 + random(10,20), 2,2); } // vertical ellipse(x+hx/2, y-5, 2,2); ellipse(x+hx/2, y+5, 2,2); boolean left = random(1) < 0.5; if(left) { ellipse(x+hx/2-random(10,20), y-random(5,10), 2,2); ellipse(x+hx/2-random(10,20), y+random(5,10), 2,2); } else { ellipse(x+hx/2+random(10,20), y-random(5,10), 2,2); ellipse(x+hx/2+random(10,20), y+random(5,10), 2,2); } } }
we're over-generating here, i'll leave figure out how prevent "piece joiner" coordinates being computed right-most , lowest-most edges (which should easy).
now then: let's turn coordinate grid, because that's looking pretty good, , should pretty nice piece joiners using catmull-rom:
beauty.
for (int x = hx/2; x<width; x+=hx) { (int y = hy/2; y<height; y+=hy) { // horizontal int xs = x-hx/2, ym = y+hy/2, xe = x+hx/2; float x3, x4, y1, y2, x1 = x-5, x2 = x+5; boolean = random(1) < 0.5; x3 = x - random(5, 10); x4 = x + random(5, 10); if (up) { y1 = y+hy/2 - random(10, 20); y2 = y+hy/2 - random(10, 20); } else { y1 = y+hy/2 + random(10, 20); y2 = y+hy/2 + random(10, 20); } curve(xs, ym, x1, ym, x3, y1, x4, y2); curve(x1, ym, x3, y1, x4, y2, x2, ym); curve(x3, y1, x4, y2, x2, ym, xe, ym); // vertical int ys = y-hy/2, xm = x+hx/2, ye = y+hy/2; y1 = y-5; y2 = y+5; float y3, y4; boolean left = random(1) < 0.5; y3 = y - random(5, 10); y4 = y + random(5, 10); if (left) { x1 = x+hx/2 - random(10, 20); x2 = x+hx/2 - random(10, 20); } else { x1 = x+hx/2 + random(10, 20); x2 = x+hx/2 + random(10, 20); } curve(xm, ys, xm, y1, x1, y3, x2, y4); curve(xm, y1, x1, y3, x2, y4, xm, y2); curve(x1, y3, x2, y4, xm, y2, xm, ye); } }
it should relatively obvious need perform cuts end these pieces now, if you're working system can't catmull-rom can bezier curves, conversion straight forward. preceding code's been using
curve(x1,x2,y1,y2,x3,y3,x4,y4);
but that's catmull-rom curve. equivalent curve, we can use bezier segment of form:
bezier( x2, y2, x2 - (x3-x1)/6, y2 - (y3-y1)/6, x3 + (x4-x2)/6, y3 + (y4-y2)/6, x3, y3 )
and let's puzzling.
Comments
Post a Comment