Angle of view based on Ellipse - android

I need to calculate the angle of view of Camera to Object preferably in a 180 degree plane (angles ranging from 0 - 180), providing me direction.
I have so far tried using Ellipse angle or calculating one by proportion of width and height multiplied by 90, but they are not as accurate (basically I see failure & success in proceeding calculation at the same angle.
Attached are multiple views of an circle. The grid below in background (only in test) will help us understand the orientation. There is no such guidance available in real life condition but the radius of object is known.
(Can't post image due to less than desired reputation)

Related

Find width of an object from camera and sensors

I should find the width of the object in camera. I have read many posts here in a SO but none of them explained about width calculation, except the distance and height of object. So someone please guide me explaining theoretically with trignometric formulas to find the width of object. I have only one input i.e the height of camera from ground.
Thanks in advance.
Well I am answering my own question to help others having same problem.
In order to find the width follow below steps. This requires a 3D imagination to understand
1) User need to enter the height of the point of observation(that is camera height from ground) manually .
2) The object whose width is to be measured , needs to be at the same level where the person is standing.
3) We need to point at bottom of the object's start point from the same height and capture the angle.
4) Then we need to tilt the device at the same height and capture the bottom of the end point of object and measure the angle.
5) With the angle and camera height from ground, we will find the respective distance of both sides applying tan rule.
tan(θ)=opposite/adjacent
tan(θ)=height_of_camera/distance
6) From the distances we calculated in previous step and with the height of camera, using pythagorean theorem, calculate the projected distances ie.camera to the objects start and end points(imagine in 3D view)
7) Now as we have 2 sides and one angle use the following formula(cosine rule) to get the other side which is the width of the object.
Width = sqrt((s1*s1) + (s2*s2) − 2(s1)(s2)cos(θ))
s1=sideOne , s2=sideTwo

how the scale function in vector base draw app implement?

I am try to implement a hand-painted app by android (like infinite design )
and decide to use vector because it can scale and not distortion.
I think a lot and try to use the mode of viewport-horizon-world
Viewport which rely on the sizeof phone (etc 1080*1920) it is the path you see and you touch
Horizon the thing which will display on viewport
World the real coordinates of the point(which make up the path etc line
,bessel).
this model works like
first you touch the screen of phone and horizon will translate the point to the real world coordinates (if you move of scale) and save the value to world
second you can move and scale by gestures it will change the attribute of horizon etc you move left 100 and down 100 the horizon will know now it offset (100,100) and the bound will change ((0,0),(1080,1920))->((100,100),(1180,2020))
last when draw i find the path which include in horizon (calculate the bound of horizon and the bound of path) then calculate the display coordinate rely on horizonand draw the path by canvas.draw() etc
now the problem is when i just offset the horizon ,calculate the display coordinate just need to plus the offset values.but when scale it become difficult.for example a path bound in ((0,0),(100,100)) and the horizon scale 0.5 in point (500,500) i don't know the position of the bound and don't know how to calculate the anchor of new path the size and width(maybe just multiplied by the scale factor)
the function i want to implement like the viewport in svg
i think it should use coordinate mapping but how?
please give me some clue

Head tracking angle using accelerometer

I´m trying to figure out how to calculate the inclination angle of head movement, just up-down movement, not moving right-left side. I have a wearable device (I guess the problem would be the same for mobile devices) with an accelerometer sensor and it is placed on my forehead.
So far, I think is better to leave the linear acceleration out and just work with the gravity acceleration. I´m reading and reading trying to understand better what exactly I´m looking for, but my brain is not maths material. In a starting position of standing still (stationary position), all the gravity acceleration falls into an axis, lets say X. When I start producing movement with my head, for instance moving my head down (like looking to the ground), the aceleration gravity does not fall only into an axis, but two axes (would be shared, for instace between X and Z). If I´m right and this is the right approach (is it?)...
How can I calculate this angle without doing crazy maths?
This problem is exactly the same than calculating the pitch angle of an accelerometer?
Can I use for this raw data or I need to calibrated data?
To make it clear, let´s imagine that my device axes are placed in the same position than this photo and that in the starting position the gravity falls into X axis (landscape position).
EDIT
Using the following formulas for pitch and roll (thanks to #Nuclearman link)
Roll = atan2(Y, Z) * 180/M_PI;
Pitch = atan2(X, sqrt(Y*Y + Z*Z)) * 180/M_PI
And this code I wrote:
/**
* Function to calculate the inclination angle or pitch of the head movement
*/
float calcInclinationAngle(int iDataPos){
float xVal = fAccel[0][iDataPos];
float yVal = fAccel[1][iDataPos];
float zVal = fAccel[2][iDataPos];
float pitch = 0;
//Pitch in rad format
pitch = atan2(xVal, sqrt(pow(yVal,2)+pow(zVal,2)));
//Pitch in degrees
pitch = pitch * 180/PI;
return pitch;
I always get wrong angles. When the gravity force is entirely on the X axis, I get around 45 degrees (instead of 0) and if I move the device 180 degrees (just changing the gravity force signal), I get around 17-18 degrees. I have been playing with atan2 parameters, but the angles range is always the same (25-35 degrees). Just throwing a question...should I be working with calibrated data instead of raw data?
Edit 2
I have done some progress "cheating" a bit, due to I'm totally stuck. Now I normalize the data and instead of using atan, I do pitch = 1/sin(xVal), which actually gives me a range of 90 degrees which seems to fit with my device rotation (although for example it gives me 135 degrees instead of...45, but I "fix" that substracting 90 degrees to all the angles). Anyway, I need a 180 degrees range because at the moment moving backwards or forward does not make a difference in the obtained angles.
Edit adding some pictures and information
Calculating the pitch as pitch = atan2(xVal, sqrt(pow(yVal,2)+pow(zVal,2))) * (180/PI), I obtain the following angles. Just in case is useful, the accelerometer values (raw data) in the position 1 are: ACCX 2936 ACCY 2152 ACCZ 1883
Position 1 (gravity falls into X axis): 45-46 degrees
Position 2 (rotating aprox 45 from starting point): 38
Position 3 (rotating aprox 90 from starting point): 28
Position 4 (rotating aprox 180 from starting point): 18-19
Position 5 (> 180 < 360): 18-46.
SOLUTION
Just in case someone bumps into something similar in the future. The main problem was the range of the raw data. Once I mapped this into a [-1g, 1g] range and fixed a few things about the coordinates it worked.
Measure just gravity orientation. there are two approaches I know of
1.use smooth (FIR) filter to filter out quick changes
for example remember last N measurements
and output their average
this is easy and continuous but not precise
2.check for acceleration vector size
and ignore all measurements where it does not match the gravity
a=sqrt( ax^2 + ay^2 + az^2 )
if (fabs(a*scale-9.81)>0.1) ignore...
where a is size of acceleration vector
(ax,ay,az) is measured acceleration vector (local to your device)
scale is scale of your accelerometer to convert a value to actual units like [m/s^2] or [N/kg]
device accelerometers are usualy already in [g] so the scale is 9.81
9.81 is the gravity in the area of measurement
0.1 is accuracy of acceleration size check (change it to your needs)
this approach is a bit slower
and not continuous because during acceleration will not measure the output (can use last valid output)
but it is much more precise
Now the formulas should work, from what I read your axises are
x - up,down
y - left,right
z - forward,backward
do not know the orientation so just negate output angle if i hit it the wrong way
green is the gravity
blue is measured values
red is your pitch angle (ang)
ang=asin(az*scale/9.81)
do not forget to avoid using asin with parameter out of range < -1.0 , +1.0 > !!!

finding specifically where an object is for collision detection purposes

I have a square that rotates to a random angle and then travels in a straight line in the direction it is pointing. It does this by using a variable as its x axis and then calling
Variable++
Each frame.
unfortunatley i cannot work out how to return the exact position of the square because the square can be travelling at any angle and therefore doesn't rigidly follow the world coordinte grid. This means that the x variable is not the shapes x coordinate.
How do i return the shapes exact coordinates and how do i do it in such a way that i can have two squares drawn from the same class behaving differently.
So you've got a measure of distance from where the object started along its internal sideways axis and a measure of the angle between that axis and the horizontal?
If so then the formula you want is simple trigonometry. Assuming the object started at (x, y) and has travelled 'distance' units along an axis at an angle of 'angle' with the horizontal then the current position (x', y') is:
x' = x + distance * cos(angle)
y' = y + distance * sin(angle)
If you have the origin in the lower left of the screen and axes arranged graph paper style with x increasing to the right and y increasing as you go upward, that assumes that the angle is measured anticlockwise and that the object is heading along positive x when angle is zero.
If you'll permit a hand waving explanation, the formula works because one definition of sine and cosine is that they're the (x, y) coordinates of the point on the outside of a unit circle at the angle specified. It also matches with the very first thing most people learn about trigonometry, that sine is 'opposite over hypotenuse', and cosine is 'adjacent over hypotenuse'. In this case your hypotenuse has length 'distance' and and you want to get the 'opposite' and 'adjacent' lengths of a right angled triangle that coincides with the axes.
Assuming Android follows J2SE in this area, the one thing to watch out for is that Math.sin and Math.cos take an angle in radians, whereas OpenGL's rotatef takes an argument in degrees. Math.toDegrees and Math.toRadians can do the conversion for you.
When you made the shape you should have already specified its X & Y coordinates. Im not too sure what you mean when you say you cant find the coordinates?
Also make sure you do fame independent movement; currently you are adding one to your variable on every loop of your program. This means if it runs a 60 Frame Per Second(FPS) it will move 60 units, but if it runs at 30FPS it will move at half the speed

In opengl, How can I get relation between pixels and gl.gltranslatef(floatx,y,z)?

I am trying to learn opengl stuff on Android. In the gl.gltranslatef(x,y,z) call, I am shifting my texture by some units in the +ve x direction. But I am unable to find the number of pixels does 1 unit of x belong to?
Here is what I am doing:
I call gl.glviewport(0,0,width,height); // This will set my rectangle with 0,0 as lowerleft corner and then extend it to accommodate width and height.
Then
I call to gl.glfrustrum(-5,5,-7,7,3,7); // I am little confused how this call is using the dimensions I set in gl.glviewport.
How will -5 to 5 units from left to right in the above call, translate to pixels on the screen of android?
I mean if width = 320 and height = 533 pixels, then what will be the number of pixels occupied on the screen due to the gl.glfrustrum call?
I am experimenting in the gl.gltranslatef call by specifying xshift as 5.0, but it does not translate the bitmap at the right or left corner of the screen, when I increase it to 6, part of it is still visible on the screen.
Thanks
Siddhesh
In short, I am searching for the maximum number of units (in terms of X) which will represent extreme corners of my android phone screen.
glViewpoint tells it what rectangle (in pixels) your OpenGL output should be displayed in.
glFrustum tells it what coordinates in your "world" units should be mapped to that viewport.
An important point: your glFrustum call includes not only a height and width, but also a depth. Since you are specifying a Frustum, not a cube, that means anything with a Z coordinate anywhere but the very front of your frustum will be scaled down appropriately for its distance from the viewer.
As such, when you to a glTranslatef, the distance by which a particular object will move (in terms of pixels) will depend on its distance from the viewer. The further away it is from the viewer, the fewer pixels a particular sideways or up/down will translate to.
Depending on what else you're doing, one easy way to deal with this might be to use glOrtho instead of glFrustum. glOrtho gives orthographic mode, which means no perspective scaling is done, so a given X or Y distance will translate to the same number of pixels, regardless of distance from the viewer.

Categories

Resources