java - Get Pointers of Drawn Circles on Canvas (Android) -
i have class enables me draw 3 circles onto canvas. want able do, pointers of each circle once have been drawn - unsure of how i'd go this.
any appreciated, thank you!
package com.morganjames.bowlsmeasurement; import java.util.hashset; import java.util.random; import android.content.context; import android.graphics.bitmap; import android.graphics.bitmapfactory; import android.graphics.canvas; import android.graphics.color; import android.graphics.paint; import android.graphics.porterduff; import android.graphics.rect; import android.util.attributeset; import android.util.log; import android.util.sparsearray; import android.view.motionevent; import android.view.view; public class circlesdrawingview extends view { private static final string tag = "circlesdrawingview"; /** main bitmap */ private bitmap mbitmap = null; private rect mmeasuredrect; /** stores data single circle */ private static class circlearea { int radius; int centerx; int centery; circlearea(int centerx, int centery, int radius) { this.radius = radius; this.centerx = centerx; this.centery = centery; } @override public string tostring() { return "circle[" + centerx + ", " + centery + ", " + radius + "]"; } } /** paint draw circles */ private paint mcirclepaint; private final random mradiusgenerator = new random(); // radius limit in pixels private final static int radius_limit = 100; private static final int circles_limit = 3; /** available circles */ private hashset<circlearea> mcircles = new hashset<circlearea>(circles_limit); private sparsearray<circlearea> mcirclepointer = new sparsearray<circlearea>(circles_limit); /** * default constructor * * @param ct {@link android.content.context} */ public circlesdrawingview(final context ct) { super(ct); init(ct); } public circlesdrawingview(final context ct, final attributeset attrs) { super(ct, attrs); init(ct); } public circlesdrawingview(final context ct, final attributeset attrs, final int defstyle) { super(ct, attrs, defstyle); init(ct); } private void init(final context ct) { // generate bitmap used background //mbitmap = bitmapfactory.decoderesource(ct.getresources(), r.drawable.ic_launcher); mcirclepaint = new paint(); mcirclepaint.setcolor(color.blue); mcirclepaint.setstrokewidth(40); mcirclepaint.setstyle(paint.style.fill); } @override public void ondraw(final canvas canv) { (circlearea circle : mcircles) { canv.drawcircle(circle.centerx, circle.centery, circle.radius, mcirclepaint); } } @override public boolean ontouchevent(final motionevent event) { boolean handled = false; circlearea touchedcircle; int xtouch; int ytouch; int pointerid; int actionindex = event.getactionindex(); // touch event coordinates , make transparent circle switch (event.getactionmasked()) { case motionevent.action_down: // it's first pointer, clear existing pointers data clearcirclepointer(); xtouch = (int) event.getx(0); ytouch = (int) event.gety(0); // check if we've touched inside circle touchedcircle = obtaintouchedcircle(xtouch, ytouch); touchedcircle.centerx = xtouch; touchedcircle.centery = ytouch; mcirclepointer.put(event.getpointerid(0), touchedcircle); invalidate(); handled = true; break; case motionevent.action_pointer_down: log.w(tag, "pointer down"); // secondary pointers, obtain ids , check circles pointerid = event.getpointerid(actionindex); xtouch = (int) event.getx(actionindex); ytouch = (int) event.gety(actionindex); // check if we've touched inside circle touchedcircle = obtaintouchedcircle(xtouch, ytouch); mcirclepointer.put(pointerid, touchedcircle); touchedcircle.centerx = xtouch; touchedcircle.centery = ytouch; invalidate(); handled = true; break; case motionevent.action_move: final int pointercount = event.getpointercount(); log.w(tag, "move"); (actionindex = 0; actionindex < pointercount; actionindex++) { // pointer has moved, search pointer id pointerid = event.getpointerid(actionindex); xtouch = (int) event.getx(actionindex); ytouch = (int) event.gety(actionindex); touchedcircle = mcirclepointer.get(pointerid); if (null != touchedcircle) { touchedcircle.centerx = xtouch; touchedcircle.centery = ytouch; } } invalidate(); handled = true; break; case motionevent.action_up: clearcirclepointer(); invalidate(); handled = true; break; case motionevent.action_pointer_up: // not general pointer pointerid = event.getpointerid(actionindex); mcirclepointer.remove(pointerid); invalidate(); handled = true; break; case motionevent.action_cancel: handled = true; break; default: // nothing break; } return super.ontouchevent(event) || handled; } /** * clears circlearea - pointer id relations */ private void clearcirclepointer() { log.w(tag, "clearcirclepointer"); mcirclepointer.clear(); } /** * search , creates new (if needed) circle based on touch area * * @param xtouch int x of touch * @param ytouch int y of touch * * @return obtained {@link circlearea} */ private circlearea obtaintouchedcircle(final int xtouch, final int ytouch) { circlearea touchedcircle = gettouchedcircle(xtouch, ytouch); if (null == touchedcircle) { touchedcircle = new circlearea(xtouch, ytouch, 40); if (mcircles.size() == circles_limit) { log.w(tag, "clear circles, size " + mcircles.size()); // remove first circle mcircles.clear(); } log.w(tag, "added circle " + touchedcircle); mcircles.add(touchedcircle); } return touchedcircle; } /** * determines touched circle * * @param xtouch int x touch coordinate * @param ytouch int y touch coordinate * * @return {@link circlearea} touched circle or null if no circle has been touched */ private circlearea gettouchedcircle(final int xtouch, final int ytouch) { circlearea touched = null; (circlearea circle : mcircles) { if ((circle.centerx - xtouch) * (circle.centerx - xtouch) + (circle.centery - ytouch) * (circle.centery - ytouch) <= circle.radius * circle.radius) { touched = circle; break; } } return touched; } @override protected void onmeasure(final int widthmeasurespec, final int heightmeasurespec) { super.onmeasure(widthmeasurespec, heightmeasurespec); mmeasuredrect = new rect(0, 0, getmeasuredwidth(), getmeasuredheight()); } }
this mathematical algorithm.
1. define point(x,y) on circle has centre point of(centerx,centery)
2.the distance of these 2 points radius,named r.
3. r = math.sqrt(math.pow(x-centerx),2)+math.pow(y-centery,2));
4. math.abs(y-centery) = math.sqrt(math.pow(r,2)-math.pow(x-centerx,2))
5. y= centery ± math.sqrt(math.pow(r,2)-math.pow(x-centerx,2))
6. know x's value is[centerx-r,centerx+r]
7.so can calculate y´s value , points 1 circle (x,y) figured out.
Comments
Post a Comment