Rotating GoogleMaps InfoWindow anchor point - android

When a GoogleMaps marker is rotated, I would like to move the anchor point of the InfoWindow to always be at the bottom, but offset by a larger amount than the size of the marker itself.
I made a drawing to describe my problem, but unfortunately I don't have enough reputation to upload an image.
Edit - this link hopefully works: https://i.stack.imgur.com/hM9nc.png
The code below works for Point B.
I want to move to Point C
This code (found in this answer) works well moving the anchor point to the top [0.5, 0]:
var angle = 130.0;
var x = Math.sin(-angle * Math.PI / 180) * 0.5 + 0.5;
var y = -(Math.cos(-angle * Math.PI / 180) * 0.5 - 0.5);
marker.setInfoWindowAnchor((float)x, (float)y);
However I have not been successful in adjusting it for a point located beyond the bottom, at [0.5,1.5].
I think this is because the x and the y offsets are different sizes.
NB Info Window anchor points can be beyond the 0,0 - 1,1 range, I'm just struggling to make the mathematical calculation

Related

Custom View - digits and alphabets on the circumference of a circle

Can anyone explain to me what is the cause of this behavior?
The problem is that, from "off" to "2" always shows perfectly, above the radius I gave.
Radius is +35 than the circle's radius.
Now when I write digits, as it goes down, it starts to mess up.
And in terms of alphabets, it touches the edge and overlaps it.
can anyone tell me the reason for this? because radius is always more than the current circle's radius so the alphabets should appear similarly like "off".
computation of xy points...
// Angles are in radians.
val startAngle = Math.PI * (9 / 8.0)
val angle = startAngle + pos.ordinal * (Math.PI / 4)
x = (radius * cos(angle)).toFloat() + width / 2
y = (radius * sin(angle)).toFloat() + height / 2
I played around with the degrees and it seems like the closer to 0 degree starts to mess up, as the degrees increase, it keeps adding more space in radius.
Illustrated here... I would like to what what is causing this behavior, or just explain the reason/ math behind it. thanks
From the comments it looks like you are following this code lab code https://github.com/google-developer-training/android-advanced/tree/master/CustomFanController
You just need to take into account text ascent and decent. So draw the numbers on the circumference of the circle
val yPos = (pointPosition.y - (paint.descent() + paint.ascent()) / 2).toInt()
canvas.drawText(label, pointPosition.x, yPos.toFloat(), paint)
The above is based on Android Center text on canvas
This does draw the text at the correct place, but if the text is too large it does overlap

Center camera in GVR MonoscopicView

I'm using GVR Android library version 1.190 and trying to play both 360 and 180 degrees videos in the video360 example project.
In both cases the 2D view (MonoscopicView) starts the playback fine, but the viewer camera position is never centered to the center of the video. It instead starts randomly off-centered by horizontal axis. Same behavior on multiple devices.
Anyone knows how to center the view to the video center when 2D view starts?
Turns out that sensor data from Sensor.TYPE_GAME_ROTATION_VECTOR are having very different values (angles) every time my activity register a listener to it. It only takes a small tilt of the phone to get really different values. Different devices also respond differently but they all have offset readings.
This lead to the initial view angle being positioned (usually) 90 degrees either to the left or right from the center of video.
Thanks to this post, I managed to calculate the initial heading offset and rotate phone position matrix to compensate.
Add a member variable private float initialHeading with initial value 0.
Then, in PhoneOrientationListener's onSensorChanged add the following code after the Android to OpenGL matrix rotation:
if (initialHeading == 0) {
initialHeading = (float) ((angles[0] + 2 * Math.PI) % (2 * Math.PI));
}
float angle = (float) ((Math.PI - initialHeading) * 180 / Math.PI);
Matrix.rotateM(phoneInWorldSpaceMatrix, 0, angle, 0, 1, 0);

Rotating bitmap on a canvas in Android studio

Can anyone point me in the right direction to find out how to write expressions for rotating a canvas in android studio. I'm making a watchface and I used part of the code from the provided sample but I need to understand what it means. Here's a part of the code:
float minuteRotation = time.minute/ 30f * (float) Math.PI
If this can be translated in dummy terms so I can understand how they arrive at those values.
if you look at the unit circle Math.PI is at one side and 0 is at the other side, say 0 is time.minute/30 = 0 * Math.PI = 0 or if 30 is time.minute/30 * Math.PI = 1 * Math.PI = Math.PI witch is the other side of the unit circle just like a watch
Your minuteRotation variable represents the ANGLE through which you will need to rotate the canvas in order to draw the minute hand in the right position.
According to the Android APIs this angle must be specified in Radians (not in Degrees), hence the use of the value "Math.PI".
PI radians represents HALF OF A COMPLETE ROTATION, i.e. 180 degrees - a half circle.
It is being used (in the expression that you described) merely as a SCALING FACTOR.
An alternative(and clearer,) way of writing the same equation would be :
minuteRotation = (time.minute/ 60.0f) * (float) Math.PI * 2.0f
This alternative version makes clearer the meaning of the various numbers:
- "60.0" is a floating point number that represents the maximum number of minutes possible(in a full rotation)
- "Math.PI * 2" radians is the angular equivalent of a FULL CIRCLE ROTATION (i.e. 360 degrees)
The fraction "time.minute/60.0" therefore represents the fraction of a full hour currently being used up.
Multiplying this by the expression PI*2 then yields the equivalent portion of a full circle expressed as an ANGLE (in Radians).
canvas.save();
canvas.rotate(45);
canvas.drawRect(166, 748, 314, 890, paint);
canvas.restore();
where 45 - is degrees

Calculate angle of moving ball after collision with angled or sloped wall that is a 2D line segment

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

Calculating points of a circle dynamically in an Android game

If my X co-ordinates increment every time a frame is drawn, what formula can I employ from the math library in order to have the Y co-ordinate moving around the circumference of a circle frame by frame, creating the illusion of an orbiting object around a continuously moving central point?
I have seen it may involve sin or cos but am not sure how to adjust the variables accordingly per frame.
Many thanks for your help
You can't make a complete circle if your X coordinate increments every time, because half the time your X coordinate has to be decrementing.
What you want is polar coordinates: theta for angle and r for radius. Your r will remain constant, and your theta will increment continuously. Then your x and y are:
x = r * cos(theta)
y = r * sin(theta)
let ox,oy be the origin of your circle, and px,py be a point on the edge of the circle, with a radius of r
given: (px-ox)^2 + (py-oy)^2 = r^2 definition of circle
solve for py:
(py-oy)^2 = r^2 - (px-ox)^2
(py-oy) = sqrt(r^2 - (px-ox)^2)
py = sqrt(r^2 - (px-ox)^2) + oy <---
So as you increment px with your frames, you can find the appropriate py by recalculating the above formula.

Categories

Resources