I am facing problem for rotating 3d model object. when i load my 3d object in GLSerfaceView with Scene Object the rotation is not working properly.
when i touch the screen and move down means top to bottom then it is working fine as i expected. but when i touch the screen from left to right the it is not rotate as i expected.
glSurfaceView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch(motionEvent.getAction()){
case MotionEvent.ACTION_DOWN:
previousX = motionEvent.getX();
previousY = motionEvent.getY();
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_MOVE:
x = motionEvent.getX();
y = motionEvent.getY();
float deltaX = (x - previousX) / density / 2f;
float deltaY = (y - previousY) / density / 2f;
objModel.rotation().x = objModel.rotation().x + deltaY;
objModel.rotation().y = objModel.rotation().y + deltaX;
previousX = x;
previousY = y;
break;
}
return true;
}
});
Related
I have to an ImageView named imgForeground which can be rotated, zoomed and moved but it can move to outside the screen. how can I restrict its movement not to go outside of screen? Is there any library for this? it is something like the apps that you can select a label, move and resize it and place it everywhere you want.
<ImageView
android:id="#+id/imgForground"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:src="#drawable/icon" />
This code for zoom, move and rotate:
#Override
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
view.setScaleType(ImageView.ScaleType.MATRIX);
float scale;
// Dump touch event to log
dumpEvent(event);
// Handle touch events here...
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: //first finger down only
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
Log.d(TAG, "mode=DRAG");
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
}
lastEvent = new float[4];
lastEvent[0] = event.getX(0);
lastEvent[1] = event.getX(1);
lastEvent[2] = event.getY(0);
lastEvent[3] = event.getY(1);
d = rotation(event);
break;
case MotionEvent.ACTION_UP: //first finger lifted
case MotionEvent.ACTION_POINTER_UP: //second finger lifted
mode = NONE;
Log.d(TAG, "mode=NONE");
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
// ...
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x, event.getY()
- start.y);
} else if (mode == ZOOM && event.getPointerCount() == 2) {
float newDist = spacing(event);
matrix.set(savedMatrix);
if (newDist > 10f) {
scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
}
if (lastEvent != null) {
newRot = rotation(event);
float r = newRot - d;
matrix.postRotate(r, view.getMeasuredWidth() / 2,
view.getMeasuredHeight() / 2);
}
}
break;
}
// Perform the transformation
view.setImageMatrix(matrix);
return true; // indicate event was handled
}
private float rotation(MotionEvent event) {
double delta_x = (event.getX(0) - event.getX(1));
double delta_y = (event.getY(0) - event.getY(1));
double radians = Math.atan2(delta_y, delta_x);
return (float) Math.toDegrees(radians);
}
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float) Math.sqrt(x * x + y * y);
}
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
/**
* Show an event in the LogCat view, for debugging
*/
private void dumpEvent(MotionEvent event) {
String names[] = {"DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
"POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?"};
StringBuilder sb = new StringBuilder();
int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;
sb.append("event ACTION_").append(names[actionCode]);
if (actionCode == MotionEvent.ACTION_POINTER_DOWN
|| actionCode == MotionEvent.ACTION_POINTER_UP) {
sb.append("(pid ").append(
action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
sb.append(")");
}
sb.append("[");
for (int i = 0; i < event.getPointerCount(); i++) {
sb.append("#").append(i);
sb.append("(pid ").append(event.getPointerId(i));
sb.append(")=").append((int) event.getX(i));
sb.append(",").append((int) event.getY(i));
if (i + 1 < event.getPointerCount())
sb.append(";");
}
sb.append("]");
Log.d(TAG, sb.toString());
}
Mobile device screen is a region of plane(x,y) where (0,0) coordinate is top-left corner. You need to calculate the imageView position w.r.t screen region. In your event handler, get the position of your imageView.
int[] location = new int[2];
view.getLocationOnScreen(location);
int x = location[0];
int y = location[1];
Now get the displayed size of an image inside the image view.
int ih=view.getMeasuredHeight();//height of imageView
int iw=view.getMeasuredWidth();//width of imageView
int iH=view.getDrawable().getIntrinsicHeight();//original height of underlying image
int iW=view.getDrawable().getIntrinsicWidth();//original width of underlying image
if (ih/iH<=iw/iW)
iw=iW*ih/iH; //rescaled width of image within ImageView
else
ih= iH*iw/iW; //rescaled height of image within ImageView
Now get the width and height of screen
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int deviceHeight = displayMetrics.heightPixels;
int deviceWidth = displayMetrics.widthPixels;
If imageView moves towards left
if(x>0)
//Move towards left functionality
If imageView moves towards top
if(y>0)
//Move towards top functionality
If imageView moves towards right
if(x+iw < deviceWidth)
//Move towards right functionality
If imageView moves towards bottom
if(y+ih < deviceHeight)
//Move towards right functionality
I want to return my image to original position when I zoom out my image and the the image scale is smaller than the first initial image size
#Override
public boolean onTouch(View v, MotionEvent event)
{
ImageView view = (ImageView) v;
view.setScaleType(ImageView.ScaleType.MATRIX);
float scale = 0;
dumpEvent(event);
// Handle touch events here...
switch (event.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN: // first finger down only
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
Log.d(TAG, "mode=DRAG"); // write to LogCat
mode = DRAG;
break;
/*case MotionEvent.ACTION_UP: // first finger lifted
case MotionEvent.ACTION_POINTER_UP: // second finger lifted
mode = NONE;
Log.d(TAG, "mode=NONE");
break;*/
case MotionEvent.ACTION_UP: // first finger lifted
mode = NONE;
break;
case MotionEvent.ACTION_POINTER_UP:// second finger lifted
/*matrix.set(savedMatrix);*/
/*view.setScaleType(ImageView.ScaleType.CENTER);*/
Log.v("/h/", ""+scale);
mode = ZOOMOUT;
//When release back to position
matrix.set(savedMatrix);
Log.d(TAG, "mode=ZOOMOUT");
break;
case MotionEvent.ACTION_POINTER_DOWN: // first and second finger down
oldDist = spacing(event);
Log.d(TAG, "oldDist=" + oldDist);
if (oldDist > 5f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
Log.d(TAG, "mode=ZOOM");
}
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG)
{
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); // create the transformation in the matrix of points
}
else if (mode == ZOOM)
{
// pinch zooming
float newDist = spacing(event);
Log.d(TAG, "newDist=" + newDist);
if (newDist > 5f)
{
matrix.set(savedMatrix);
scale = newDist / oldDist; // setting the scaling of the
// matrix...if scale > 1 means
// zoom in...if scale < 1 means
// zoom out
if(scale>1) {
//Zoom In
}else if(scale<1) {
//Zoom Out
}
matrix.postScale(scale, scale, mid.x, mid.y);
Log.v("/h/", ""+scale+mode);
}
}
break;
}
view.setImageMatrix(matrix); // display the transformation on screen
return true; // indicate event was handled
}
/*
* --------------------------------------------------------------------------
* Method: spacing Parameters: MotionEvent Returns: float Description:
* checks the spacing between the two fingers on touch
* ----------------------------------------------------
*/
private float spacing(MotionEvent event)
{
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float) Math.sqrt(x * x + y * y);
}
/*
* --------------------------------------------------------------------------
* Method: midPoint Parameters: PointF object, MotionEvent Returns: void
* Description: calculates the midpoint between the two fingers
* ------------------------------------------------------------
*/
private void midPoint(PointF point, MotionEvent event)
{
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
Set savedMatrix to view.getImageMatrix() on ACTION_DOWN.
Do zoom/drag changes on a separate matrix
On ACTION_UP or ACTION_POINTER_UP set original matrix back to imageview.
view.setImageMatrix(savedMatrix)
I programmed a drawing application, I want to retrieve all the X Y of my drawing. That is to say each time I touch the screen, the coordinates x and y I put them in a two dimensional table ,
I made a toast to find out when the coordinates change, and I found that they change in the movetouch method, so I declare a table in the method and I still make a toast to see the 10 line Of my array, the toast changed co-ordination so I understood that in fact values are crushed whenever the x and y change, or I am planting
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startTouch(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
upTouch();
invalidate();
break;
case MotionEvent.ACTION_MOVE:
moveTouche(x, y);
invalidate();
break;
}
return true;
}
Method moveTouch
public void moveTouche (float x,float y ) {
if ((canDraw)&& drawing) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if(dx >= Tolerance || dy >= Tolerance){
path.quadTo(mX,mY,(x+mX)/2,(y+mY)/2);
mX = x ;
mY = y;
double[][] point = new double [99][2];
for (int i = 0; i < 99; i++) {
point[i][0]=x;
point[i][1]=y;
}
Toast.makeText(getContext(),"y = "+point[10][1]+" ",Toast.LENGTH_LONG).show();
}}
}
You can read as many points as you want from any path. Example how to read coordinates from the middle of path:
PathMeasure pm = new PathMeasure(myPath, false);
//coordinates will be here
float aCoordinates[] = {0f, 0f};
//get coordinates of the middle point
pm.getPosTan(pm.getLength() * 0.5f, aCoordinates, null);
You can pass any distance from the path start to get point coordinates.
I have an ImageView and i want to zoom/drag on by two fingers and draw on it using one finger , but after scaling ImageView , bitmap coordinates and ImageView coordinates doesn't match , to solve this i provided onTouch like this :
#Override
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
final int NONE = 0;
final int DRAW = 1;
final int PINCH = 2;
float x,y;
switch (event.getAction() & MotionEvent.ACTION_MASK){
case MotionEvent.ACTION_DOWN:
drawStartX = event.getX();
drawStartY = event.getY();
imageMode = DRAW;
break;
case MotionEvent.ACTION_POINTER_DOWN:
//drag
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
x = event.getX(0) - event.getX(1);
y = event.getY(0) - event.getY(1);
oldDistance = (float) Math.sqrt(x * x + y * y);
if (oldDistance > 5f) {
savedMatrix.set(matrix);
x = event.getX(0) + event.getX(1);
y = event.getY(0) + event.getY(1);
mid.set(x / 2, y / 2);
imageMode = PINCH;
}
break;
case MotionEvent.ACTION_UP:
imageMode = NONE;
break;
case MotionEvent.ACTION_POINTER_UP:
imageMode = NONE;
break;
case MotionEvent.ACTION_MOVE:
if (imageMode == DRAW) {
float drawEndX = event.getX();
float drawEndY = event.getY();
drawTest(drawStartX/bitmapScale - xTranslate, drawStartY/bitmapScale- yTranslate,drawEndX/bitmapScale - xTranslate,drawEndY/bitmapScale - yTranslate,0);
} else if (imageMode == PINCH) {
x = event.getX(0) - event.getX(1);
y = event.getY(0) - event.getY(1);
float newDistance = (float) Math.sqrt(x * x + y * y);
matrix.set(savedMatrix);
if(newDistance > 5f) {
//drag
float dx = event.getX() - start.x;
float dy = event.getY() - start.y;
matrix.postTranslate(dx, dy);
//zoom
float scale = (newDistance / oldDistance);
matrix.postScale(scale, scale);
}
//get matrix
float[] mat = new float[9];
matrix.getValues(mat);
bitmapScale = mat[0];
xTranslate = mat[2];
yTranslate = mat[5];
}
break;
}
view.setImageMatrix(matrix);
return true;
}
drawTest is just a void that draws a line.
pic
in before scale picture i drag my finger on imageview and line drawn in exact position , but after scaling i dragged on same position but result is not right
but it's not working properly. how can i fix it ?
I'm implementing imageview drag function to my application.
I have tried with below code but it's behaves strange.when I try to drag the image
it's changes the position and during the movement it's shows like zooming the image.
I want to move the image with finger smoothly.
please help me to solve this problem
#Override
public boolean onTouch(View v, MotionEvent event) {
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
MarginLayoutParams marginParams = new MarginLayoutParams(mImagePreView.getLayoutParams());
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
_xDelta = X - marginParams.leftMargin;
_yDelta = Y - marginParams.topMargin;
break;
case MotionEvent.ACTION_MOVE:
marginParams.leftMargin = X-_xDelta;
marginParams.topMargin = Y - _yDelta;
marginParams.rightMargin = -250;
marginParams.bottomMargin = -250;
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(marginParams);
mImagePreView.setLayoutParams(layoutParams);
break;
default:
break;
}
return true;
}
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mImagePreView.getLayoutParams();
layoutParams.leftMargin += offsetX;
layoutParams.topMargin += offsetY;
And there is error:
_xDelta = X - marginParams.leftMargin;
_yDelta = Y - marginParams.topMargin;
X - events in absolute coordinates, marginParams.leftMargin - coordinates are relative to the parent layout