I'd like to project images on a wall using camera. Images, essentially, must scale regarding the distance between camera and the wall.
Firstly, I made distance calculations by using right triangle trigonometry(visionHeight * Math.tan(a)). It's not 100% exact but yet close to real values.
Secondly, knowing the distance we can try to figure out all panorama height by using isosceles triangle trigonometry formula: c = a * tan(A);
A = mCamera.getParameters().getVerticalViewAngle();
The results are about 30% greater than the actual object height and it's kinda weird.
double panoramaHeight = (distance * Math.tan( mCamera.getParameters().getVerticalViewAngle() / 2 * 0.0174532925)) * 2;
I've also tried figuring out those angles using the same isosceles triangle's formula, but now knowing the distance and the height. I got 28 and 48 degrees angles.
Does it mean that android camera doesn't render everything it shoots ? And, what other solutions you can suggest ?
Web search shows that the values returned by getVerticalViewAngle() cannot be blindly trusted on all devices; also note that you should take into account the zoom level and aspect ratio, see Determine angle of view of smartphone camera
Related
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)
I have created one RectangularPrism with default camera in Rajawali 1.1.777:
RectangularPrism p = new RectangularPrism(2f, 2f, xf);
Depending on x (depth) the perceived width on the Android screen varies.
If the depth is 2f the width of the prism fills the screen.
If the depth is 0.5f & 1f the width of the prism does not fill the screen.
So from a Rajawali/OpenGL perspective how and why does the depth parameter affect the perceived width of the object on the screen? Since the width (2f) is kept static shouldn't the prism always fill the screen in the same way?
0.1f:
1f:
2f:
Answer from https://github.com/Rajawali/Rajawali/issues/1883
The default camera is a Perspective Camera, faces in the distance appear smaller than faces close by. The default camera is located at 0,0,4 and looks at 0,0,0. If one places a RectangularPrism of size 2,2,0.5 at 0,0,0, the distance between the camera and the closest face is 3.75. If one places a RectangularPrism of size 2,2,2 at 0,0,0, the distance between the camera and the closest face is only 3, and so the closest face appears bigger.
If perspective is not desired, one may instantiate an Orthographic Camera and getCurrentScene().addAndSwitchCamera(orthographicCamera).
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
I'm developing an android "radar" in which I will show a gps coordinates in my android screen. So I have to convert the latitude and longitude to the pixels (x, y) of the device screen. To do that I though in take the center of the screen like (0, 0) and transform the coordinates of (lat, lng) to my screen pixels (x, y).
The problem is that I dont know how to implement this. I think the idea would sucess but I dont know how the screen works, the pixel coordinates, etc.
Any tips pls?
Thanks
Android supports many different screen orientations. Because of this, it is HIGHLY UNADVISED to EVER use absolute pixels.
The best way to accomplish what you are trying to do is likely through the OpenGL ES API.
If all you want to do is get the "center" of the display, you can use the following:
int centX = WindowManager.getDefaultDisplay().getWidth() / 2;
int centY = WindowManager.getDefaultDisplay().getHeight() / 2;
Hope this helps!
If you have a "ball" inside a 2D polygon, made up of say, 4 line segments that act as bounding walls, how do you calculate the angle of the ball after the collision with the irregularly sloped wall?
I know how to make the ball bounce if the wall is horizontal, vertical, or at a 45 degree angle. I also have my code setup to detect a collision with the wall.
I've read about dot products and normals, but I cannot figure out how to implement these in Java / Android. I'm completely stumped and feel like I've looked up everything 10 pages deep in Google 10 times now. I'm burned out trying to figure this out, I hope someone can help.
Apologies in advance: I don't know the correct Android types. I'm assuming you have a vector type with properties 'x' and 'y'.
If the wall were horizontal and the current velocity were 'vector' then it'd be as easy as:
vector.y = -vector.y;
And you'd leave the x component alone. So you need to do something analogous, but more general.
You do that by substituting the idea of the line normal (a vector perpendicular to the line) for hard coding for the y axis (which is perpendicular to the horizontal).
Since the normal is orthogonal to the line, it can be found by rotating the line by 90 degrees. In 2d, the vector (a, b) can be rotated by 90 degrees by converting it to (-b, a). Hence if you have a line from (x1, y1) to (x2, y2) then you can get the normal with:
vectorAlongLine.x = x2 - x1;
vectorAlongLine.y = y2 - y1;
normal.x = -vectorAlongLine.y;
normal.y = vectorAlongLine.x;
You don't actually care how long the original line was (and it'll affect computations later when you don't want it to), so you want to make the normal be of length 1 irrespective of its current length. You can do that by dividing it by its current length. So, e.g.
lengthOfNormal = Math.sqrt(normal.x*normal.x + normal.y*normal.y);
normal.x /= lengthOfNormal;
normal.y /= lengthOfNormal;
Using the Pythagorean theorem there to get the length.
With the horizontal line, flipping on the y axis was the same as (i) working out what the extent of the vector extends along the y axis; and (ii) subtracting that amount twice — once to get the velocity to be 0 in that direction, again to make it the negative version of the original. That is, it's the same as:
distanceAlongNormal = vector.y;
vector.y -= 2.0 * distanceAlongNormal;
The dot product is used in the general case is to work how far the vector extends along the normal. So it does the same as taking vector.y does for the horizontal line. This is where you possibly have to take a bit of a leap of faith. It's a property of the dot product and you can persuade yourself by inspecting a right-angled triangle. But for now, if you had a horizontal line, you'd have ended up with the normal (0, 1). Since the dot product would be:
vector.x * normal.x + vector.y * normal.y
You'd compute:
distanceAlongNormal = vector.x * 0.0 + vector.y * 1.0;
Which is obviously the same thing as just taking the y component.
Having worked out the distance along the normal, you actually want to then subtract that amount times the normal times two. The only additional step here is multiplying by the normal to get a 2d quantity to subtract. That's because you're looking to subtract in the order of the normal. So complete code, based on a normal computed earlier, is:
distanceAlongNormal = vector.x * normal.x + vector.y * normal.y;
vector.x -= 2.0 * distanceAlongNormal * normal.x;
vector.y -= 2.0 * distanceAlongNormal * normal.y;
If you hadn't made normal of length 1, then you'd need to divide by the length here, since the dot product would scale the distanceAlongNormal value by that amount.
This might come in handy for you
http://www.tonypa.pri.ee/vectors/tut07.html