I'm having trouble getting my program in Android Studio to properly constrain the joystick I have created. I have two ImageViews placed on top of one another, one being the joystick itself and one being the base of the joystick. Here is the code:
case R.id.analogStick:
switch(me.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
x = me.getRawX();
y = me.getRawY();
System.out.println(x);
System.out.println(y);
dx = x - v.getX();
dy = y - v.getY();
break;
case MotionEvent.ACTION_UP:
v.setX(originX);
v.setY(originY);
break;
case MotionEvent.ACTION_CANCEL:
break;
case MotionEvent.ACTION_MOVE:
float xx = originX - me.getRawX();
float yy = originY - me.getRawY();
float displacement = (float) Math.sqrt((xx * xx) + (yy * yy));
if (displacement < baseRadius) {
v.setX(me.getRawX() - dx);
v.setY(me.getRawY() - dy);
}
else {
float ratio = (float) baseRadius / displacement;
float constrainedX = originX + (me.getRawX() - originX) * ratio;
float constrainedY = originY + (me.getRawY() - originY) * ratio;
v.setX(constrainedX);
v.setY(constrainedY);
}
break;
}
break;
The main problem here is when calculating the displacement. The value turns out to be too high even when within bounds of the baseRadius, so the program always goes to the else statement, executing the constrained joystick case at all times. I get the base radius by the following formula: baseRadius = baseJoystickImage.getWidth() / 2, with baseJoystickImage being an ImageView variable. I'm not sure what could be going wrong here, any help would be appreciated.
Related
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'm looking for developing a remote control app to my PC, One of my tools on my project is moving cursor with touch gesture
I use Motion Event for tracking pointers, I have tried many times but there's no sensitivity.
This is my first try
case MotionEvent.ACTION_DOWN:
lastX = event.getX();
lastY = event.getY();
lastTime = System.currentTimeMillis();
break;
case MotionEvent.ACTION_UP:
break;
default:
float xx = event.getX() - lastX;
float yy = event.getY() - lastY;
x = xx*speed;
y =yy*speed;
lastX = event.getX();
lastY = event.getY();
break;
Speed is a constant
Then i send x , y to a C# program to move cursor, but it didn't work very good, It was really slow for a big move, So i tried to increase speed but it became very bad for a small move such as clicking on Exit icon.
So i tried not to make speed a constant i make it depends on some thing change when x&y change, Some thing like distance.
This is my second try
double distance = Math.sqrt((xx * xx) + (yy * yy));
speed =(float)(distance*c);
C is a constant to make distance greater or lower
But it wasn't very good, it didn't have any sensitivity, I can't make a circle with it and some times it goes far away from what i want
And this is my C# Code
private void linearSmoothMove(Point newPosition, TimeSpan duration)
{
Point start = Cursor.Position;
// Find the vector between start and newPosition
double deltaX = newPosition.X - start.X;
double deltaY = newPosition.Y - start.Y;
if (moving == null || !moving.IsAlive)
{
moving = new Thread(() =>
{
// start a timer
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
double timeFraction = 0.0;
do
{
timeFraction = (double)stopwatch.Elapsed.Ticks / duration.Ticks;
if (timeFraction > 1.0)
timeFraction = 1.0;
int intX = start.X + ((int)Math.Round(timeFraction * deltaX));
int intY = start.Y + ((int)Math.Round(timeFraction * deltaY));
Console.WriteLine(intX + "," + intY);
Cursor.Position = new Point(intX, intY);
Thread.Sleep(5);
} while (timeFraction < 1.0);
});
moving.Start();
}
}
newPosition is x&y come from android.
Any suggestion for better performance ?
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;
}
});
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 ?
zoom jumps around when I remove my finger and put it again ! anybody knows the problem ?
boolean surfaceTouchEvent(MotionEvent event) {
pointNum=event.getPointerCount();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_POINTER_DOWN:
// User is pressing down another finger.
float x11 = event.getX(0) - event.getX(1);
float y22 = event.getY(0) - event.getY(1);
z4 = sqrt(x11*x11+y22*y22);
break;
case MotionEvent.ACTION_POINTER_UP:
// User is released one of the fingers.
break;
case MotionEvent.ACTION_MOVE:
if (pointNum >= 2 ) {
x1=event.getX(0);
x2=event.getX(1);
y1=event.getY(0);
y2=event.getY(1);
float x = event.getX(0) - event.getX(1);
float y= event.getY(0) - event.getY(1);
float z3 = sqrt(x*x+y*y);
if (pointNum >= 2 ) {
if ( z3 < z4 ) {
zoom = z3/z4;
}
else {
zoom = z3/z4;
}
zoom = constrain(zoom, 0, 100);
}
press1=event.getSize(0);
press2=event.getSize(1);
}
break;
}
return super.surfaceTouchEvent(event);
}