java - Apply rotation angle to coordinates around origin? -
i working on drawing app user can create rectangle, row of holes, grid of holes, , polygons. right have functionality move these objects determining if touch point within bounds of object, updating objects coordinates during touchmove action, , redrawing object (along else drawn) updated coordinates. next step implement rotation. far able rotation angle, use rotate canvas when drawing rotated object, , restore canvas other objects drawn without angle. works perfectly. problem comes when try move/rotate rotated object. store objects rotation, don't update it's stored coordinates; when try determine if user has touched rotated object doesn't match user sees on screen. need able either modify objects coordinates or touch coordinates reflect rotation. there way this? going wrong?
here's snippets of code:
this determines if grid of circles has been touched:
//retrieve touch coordinates. adjust matrix transformations float currx=(event.getx()-matrixvalues[2])/matrixvalues[0]; float curry=(event.gety()-matrixvalues[5])/matrixvalues[4]; //... skip other code snippet else if(drawobject.getdrawaction()=="array") { arraylist <drawaction> redrawarray=drawobject.getdrawarray(); if(drawmode=="remove") { //determine hole in grid touched. "remove" for(int y=0; y<redrawarray.size();y++) { drawaction arrayaction=redrawarray.get(y); if(currx>(arrayaction.getdrawx()-arrayaction.getdrawradius()) && currx<(arrayaction.getdrawx()+arrayaction.getdrawradius()) && curry<(arrayaction.getdrawy()+arrayaction.getdrawradius()) && curry>(arrayaction.getdrawy()-arrayaction.getdrawradius())) { arrayaction.setremoved(true); //add undo object action drawaction undoremove= new drawaction("remove", arrayaction); undolist.add(undoremove); //redraw objects updated status redrawobjects(false); break outerloop; } } } else { //determine coordinates within grid. if within grid, want move whole grid float holeradius=redrawarray.get(0).getdrawradius(); float lowestx=redrawarray.get(0).getdrawx()-holeradius; float lowesty=redrawarray.get(0).getdrawy()-holeradius; float highestx=redrawarray.get(redrawarray.size()-1).getdrawx()+holeradius; float highesty=redrawarray.get(redrawarray.size()-1).getdrawy()+holeradius; if(currx>lowestx && currx<highestx && curry>lowesty && curry<highesty) { touchobject=drawobject; //store coordinates new coordinate calculations touchedx=currx; touchedy=curry; break outerloop; } }
}
this snippet how determine angle:
touchobject.setrotationangle((float) getdegreesfromtouchevent(currx, curry)); touchobject.setrotated(true);
this function returns angle:
//determine rotation touch event , screen dimensions private double getdegreesfromtouchevent(float x, float y){ double delta_x = x - (screenwidth) /2; double delta_y = (screenheight) /2 - y; double radians = math.atan2(delta_y, delta_x); return (-1)*math.todegrees(radians); }
and here's redraw after movement/rotation:
//redraw for(int x=0; x<undolist.size();x++) { //retrieve next object draw drawaction drawobject=undolist.get(x); //retrieve object's brush width/paint color this.setbrushsize(drawobject.getbrushwidth()); drawpaint.setcolor(drawobject.getpaintcolor()); //save state of canvas. can rotate it, draw, , rotate original state drawcanvas.save(); //if object has been rotated, need rotate canvas before drawing if(drawobject.isrotated()) { drawcanvas.rotate(drawobject.getrotationangle(),drawobject.getcenterx(),drawobject.getcentery()); } if(drawobject.getdrawaction()=="circle" && !drawobject.isremoved()) { drawcanvas.drawcircle(drawobject.getdrawx(), drawobject.getdrawy(), drawobject.getdrawradius(),drawpaint); } if(drawobject.getdrawaction()=="rectangle") { if(!drawobject.isremoved()) { drawcanvas.drawrect(drawobject.getdrawleft(), drawobject.getdrawtop(), drawobject.getdrawright(), drawobject.getdrawbottom(),drawobject.getdrawpaint()); drawcanvas.drawcircle(drawobject.getcenterx(), drawobject.getcentery(), 2, drawobject.getdrawpaint()); } } if(drawobject.getdrawaction()=="text" || drawobject.getdrawaction()=="delay") { drawcanvas.drawtext(drawobject.getdrawtext(), drawobject.getdrawx(), drawobject.getdrawy(), drawobject.getdrawpaint()); } if(drawobject.getdrawaction()=="array") { arraylist <drawaction> redrawarray=drawobject.getdrawarray(); for(int y=0; y<redrawarray.size();y++) { drawaction arrayaction=redrawarray.get(y); if(!arrayaction.isremoved()) { drawcanvas.drawcircle(arrayaction.getdrawx(), arrayaction.getdrawy(), arrayaction.getdrawradius(),drawpaint); } } } if(drawobject.getdrawaction()=="path") { drawcanvas.drawpath(drawobject.getdrawpath(), drawpaint); } //restore canvas original state drawcanvas.restore(); }
@pskink's solution great. took tweaking work code, took day. had change being drawn directly on main canvas being drawn on own bitmap. bitmap has dimensions of object drawn on it. these bitmaps stored in linkedlist of bitmap layers , added main bitmap via canvas.drawbitmap(bitmap, x, y, null);
here's link example: android imageview scaling , translating issue
and source:https://github.com/pskink/android-gesture-detectors
Comments
Post a Comment