I'm working on a project where i detect finger movement in order to move the cursor on the screen so i have to translate the coordinates i get from the image to coordinates on the screen and move the cursor there.
example: the finger is detected on (128,127) i want to find the equivalent of that point on the screen. Image is (640 x 480) and the screen is (1366 x 768).
Can anybody help me with this. tried different methods but nothing is satisfying some of them i found on stack-overflow.
thanks in advance.
Try this:
ScreenX = event.X / PhoneWidth * ScreenWidth
ScreenY = event.Y / PhoneHeight * ScreenHeight
Where event.X would be the X coordinate where the user touched the screen.
Try using a map function.
In c language it could look like this:
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
Related
I'm trying to get a PositionComponent to rotate around a central fixed point in the game world, the anchors are all within the component itself so I'm a bit stumped.
Edit: Just for anyone else looking to do something similar managed to get it to work with
void update(double dt){
super.update(dt);
double oldRadian = anchorComponent.angle;
anchorComponent.angle += rotation * dt;
anchorComponent.angle %= 2 * math.pi;
double newRadian = anchorComponent.angle - oldRadian;
rotatingComponent.angle = anchorComponent.angle;
double x = rotatingComponent.position.x;
double y = rotatingComponent.position.y;
rotatingComponent.position.x = cos(newRadian) * (x - anchorComponent.position.x) -
sin(newRadian) * (y - anchorComponent.position.y) +
anchorComponent.position.x;
rotatingComponent.position.y = sin(newRadian) * (x - anchorComponent.position.x) +
cos(newRadian) * (y - anchorComponent.position.y) +
anchorComponent.position.y;
}
Now rotatingComponent rotates around anchorComponent (both positionComponents) when variable rotation changes.
You can use a MoveAlongPathEffect to make the component move in a circle around a point and then you can combine that with the lookAt method to make the component rotate "inwards" so that it looks like it is rotating around the point. You might have to set nativeAngle too, depending on how the PositionComponent that you want to rotate looks like.
How Can I find extreme left, right, top, bottom points of perspective camera in Unity 3D. I am trying to do zooming and panning. I need those points to check if I am going out of my Bound. Is there any other way to find?
This unity manual entry directly answers your question:
FrustumSizeAtDistance
So to summarize:
To calculate the height of the view frustum at a given distance we can calculate it like so:
var frustumHeight = 2.0f * distance * Mathf.Tan(camera.fieldOfView * 0.5f * Mathf.Deg2Rad);
If we already know the frustumHeight we can calculate the corresponding distance to the camera:
var distance = frustumHeight * 0.5f / Mathf.Tan(camera.fieldOfView * 0.5f * Mathf.Deg2Rad);
Once we have the frustumHeight at a given distance we can calculate its width by using the cameras aspect:
var frustumWidth = frustumHeight * camera.aspect;
This can also be reversed like so:
var frustumHeight = frustumWidth / camera.aspect;
Camera.ScreenToWorldPoint will assist you.
For instance, to find bottom-left point of the screen projected onto the world, use this:
camera.ScreenToWorldPoint(new Vector3(0, 0, distance_from_camera));
The question I am about to ask could be somewhat challenging. I will try to make this as clear and cohesive as possible.
I am currently making a game, in which I have a 'laser ring,' as shown here:
This laser ring, when prompted, will fire a 'grappling hook' which is simply the image shown below. This image's frame.width property is adjusted to make it fire (lengthen) and retract (shorten.) It starts at a width of 0, and as the frames progress, it lengthens until reaching the desired point.
This grappling hook, when fired, should line up with the ring so that they appear to be one item. Refer to the image below for clarity:
*Note that the grappling hook's width changes almost every frame, so a constant width cannot be assumed.
Something else to note is that, for reasons that are difficult to explain, I can only access the frame.center property of the grappling hook and not the frame.origin property.
So, my question to you all is this: How can I, accessing only the frame.center.x and frame.center.y properties of the grappling hook, place it around the laser ring in such a way that it appears to be seamlessly extending from the ring as shown in the above image - presumably calculated based on the angle and width of the grappling hook at any given frame?
Any help is immensely appreciated.
OK, I've done this exact same thing in my own app.
The trick I did to make it easier was to have a function to calculate the "unitVector" of the line.
i.e. the vector change in the line based on a line length of 1.
It just uses simple pythagorus...
- (CGSize)unitVectorFromPoint:(CGPoint)start toPoint:(CGPoint)end
{
//distance between start an end
float dX = end.x - start.x;
float dY = end.y - start.y;
float distance = sqrtf(dX * dX + dY * dY); // simple pythagorus
//unit vector is just the difference divided by the distance
CGSize unitVector = CGSizeMake(dX/distance, dY/distance);
return unitVector;
}
Note... it doesn't matter which way round the start and end are as squaring the numbers will only give positive values.
Now you can use this vector to get to any point along the line between the two points (centre of the circle and target).
So, the start of the line is ...
CGPoint center = // center of circle
CGPoint target = // target
float radius = //radius of circle
float dX = center.x - target.x;
float dY = center.y - target.y;
float distance = sqrtf(dX * dX + dY * dY);
CGSize unitVector = [self unitVectorFromPoint:center toPoint:target];
CGPoint startOfLaser = CGPointMake(center.x + unitVector.x * radius, center.y + unitVector.y * radius).
CGPoint midPointOfLaser = CGPointMake(center.x + unitVecotr.x * distance * 0.5, center.y + unitVector.y * distance * 0.5);
This just multiplies the unit vector by how far you want to go (radius) to get to the point on the line at that distance.
Hope this helps :D
If you want the mid point between the two points then you just need to change "radius" to be the distance that you want to calculate and it will give you the mid point. (and so on).
I am developing an application using multi-touch in AndEngine. To get the coordinates of touching fingers I use pSceneTouchEvent.getMotionEvent().getX([pointer index]) because TouchEvent doesn't have an equivalent getter, only pSceneTouchEvent.getX().
The problem is that MotionEvent returns coordinates on the screen while TouchEvent returns coordinates on the Scene. When I zoom in or out, the screen and Scene coordinates do not match, so I need to convert the screen coordinates to Scene coordinates. How can I do that?
Faced with the same problem and have a solution. First I want to explain it and then will paste the convert method.
The problem
Coordinates you want to have is scene coordinates which are related to your scene start point (0,0) (i.e. AndEngine anchorCenter is bottom-left). Bounds: from (0,0) to [Camera.getSurfaceWidth(), Camera.getSurfaceHeight()].
Coordinates you've got from MotionEvent is screen coordinates with bounds from (0,0) to [displayMetrix.widthPixels, displayMetrix.heightPixels] and they're independat of zoom or camera-to-scene-position.
Solution explanation
For the abscissa (in general x) you must translate screen corrdinates to relevant scene coordinates (bounded with camera width) and sum the up to the camera left corner position (on the scene). In formula it looks like:
x = cameraStartX + screenX * camera.width / display.width
cameraStartX - the camera left corner x position on the scene
screenX - x you get from MotionEvent
camera.width - just getWidth() from your camera method
display.width - display width from DisplayMetrics
For the ordinate (in general y) you have to do the same as for the abscissa but remember that it has a different direction. So the formula will be a bit changed:
y = cameraStartY+(display.heigth-screenY)*camera.height/display.heigth
cameraStartY - camera left corner y position on the scene
screenX - y you get from MotionEvent
camera.height - just getHeight() from your camera method
display.height - display height from DisplayMetrics
The method implementation example
public static void convertScreenToSurfaceCoordinates(
final Camera camera,
final Context context,
final float[] screenCoordinates,
final float[] surfaceCoordinates) {
//you may want to have a separate methods and fields for display metrics
//and no Context as a method param
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
float displayWidth = Math.max(metrics.widthPixels, metrics.heightPixels);
loat displayHeight = Math.min(metrics.widthPixels, metrics.heightPixels);
//abscissa
surfaceCoordinates[Constants.VERTEX_INDEX_X] = camera.getXMin()
+ screenCoordinates[Constants.VERTEX_INDEX_X] * camera.getWidth()
/ displayWidth;
//ordinate
surfaceCoordinates[Constants.VERTEX_INDEX_Y] = camera.getYMin()
+ (displayHeight - screenCoordinates[Constants.VERTEX_INDEX_Y])
* camera.getHeight() / displayHeight;
}
Solution found. Andengine handles touch events in a different way to Android so there is no history of touch coordinates. I simply store them myself in private variables before handling the event:
if (pSceneTouchEvent.getPointerID() == 0) {
pointer0LastX = pSceneTouchEvent.getX();
pointer0LastY = pSceneTouchEvent.getY();
}
if (pSceneTouchEvent.getPointerID() == 1) {
pointer1LastX = pSceneTouchEvent.getX();
pointer1LastY = pSceneTouchEvent.getY();
}
Then I just access these instead of getting the values from the TouchEvent.
You can access the original MotionEvent from the TouchEvent.
Through swipe gesture, is it possible to calculate the distance of swipe (up, down, left, right)?
- (CGFloat)distanceBetweenTwoPoints:(CGPoint)fromPoint toPoint:(CGPoint)toPoint
{
float x = toPoint.x - fromPoint.x;
float y = toPoint.y - fromPoint.y;
return sqrt(x * x + y * y);
}
Hope its help you, just pass starting and endpoint to this method ....
I've used an approach similar to this article to recognise swipe gestures of a certain number of pixels, but if you're using a base SDK of at least 4 try using UISwipeGestureRecognizer which can make it much easier; see this post.