Tracking drag around multiple pivot points with touch input - algorithm

Suppose that in 2D I have a polygon consists of square cells on a grid, much like a tetronimo but with an arbitrary number of cells that form it. The shape is orthogonally continuous, as in every cell connects to at least one other cell in an orthogonal direction. Here are some examples:
In the project I am working on, these blocks can be moved with the arrow keys in multiple directions around multiple pivot points. For example, this shape below can rotate around any of 4 directions by pressing, in order of rotations shown, the left, down, right and up arrow keys. The shape rotates around the pivot points shown in red.
I would like to add "drag-to-move" support. In other words, you press your finger down onto any point upon the shape, and as you drag and rotate your finger around a pivot point, the shape will rotate with it accordingly. My problem is that I do not know how to go about programatically finding the pivot point to rotate around, or the direction of rotation, from the path of the player's finger alone.
In code, I store a list of pivot points as Vector3s. These Vector3s store the following information:
X-component: x-pos of pivot
Y-component: y-pos of pivot
Z-component: -1 or 1, direction of rotation (1 for clockwise, -1 for anti-clockwise)
For clarity, the Z-component determines which direction the shape can be rotated about a pivot if it is to be rotated. Therefore, the above GIF will might have the following 4 entries:
Entry #1: (0, 0, -1)
Entry #2: (0, 0, 1)
Entry #3: (2, 1, -1)
Entry #4: (2, 1, 1)
Notice 2 entries for each x-y position in this case, as the shape can be rotated in both directions.
I am familiar with Unity's touch system although it is not much help to me here. I plan to use Transform.RotateAround(Vector3 point, Vector3 axis, float angle) to rotate the shape around a pivot and axis incrementally every frame, but I don't know how to calculate, from the player's touch input and touch position, which pivot and by what angle to rotate.
I have seen posts like this and this (using mouse input), and while they would be helpful were I dealing with only one pivot, I am dealing with potentially 2 and even 3 pivot points. Were only one pivot involved, I might try to check the angle difference every frame (the angle between the pivot, current position, and last frame position) and use Transform.RotateAround. Since there are two pivots, I first determine which pivot to rotate around, and then possibly calculate the angle deltas. However I don't know what the best way would be to go about finding which pivot to rotate around. Any ideas?
Apologies for the very long post, thanks for any and all help you can provide! Ask me to clarify anything.
rbjacob

Related

How to represent a sphere surface in computer memory?

As the title suggest my problem lies in some representation of a sphere surface in computer memory. For simplicity, let's say we are making a chess game where the board is on a sphere. If the board was a classic flat board, then the solution is simple: use a 2D table.
But I don't know what kind of a memory structure I should chose for a sphere. Namely, what I want from this representation are:
If I move a pawn stubbornly in one direction, then I should return to the point where I started,
During such "journey" I should cross a point directly on the other side of the sphere (I mean to avoid a common "error" in a 2D game where moving pass an edge of a board will move an object to the opposite edge, thus making the board a torus, not a real sphere)
the area of one board cell should be approximately equal to any other cell
a cell should have got an associated longitude-latitude coordinates (I wrote "associated" because I want from the representation to only have got some way to obtain these coordinates from the position of a cell, not to be eg. a table with lat-long indexes)
There's no simple geometric solution to this. The crux of the problem is that, say you have n columns at the equator, and you're currently near the north poll, and heading north. Then the combination of the direction and the column number from the top row (and second from top row) must be able to uniquely identify which one of the n positions at the equator that path is going to cross. Therefore, direction could not be an integer unless you have n columns in the top (or second to top) row. Notice that if the polygons have more than three sides, then they must have common edges (and triangles won't work for other reasons). So now you have a grid, but if you have more than three rows (i.e. a cube, or other regular prism), then moving sideways on the second-to-top row will not navigate you to the southern hemisphere.
The best bet might be to create a regular polyhedron, and keep the point and direction as floating point vectors/points, and calculate the actual position when you move, and figure out which polygon you land in (note, you would have the possibility of moving to non-adjacent polygons with this method, and you might have issues if you land exactly on an edge/vertex, etc).

Algorithm to find raycast to "special" capsule

I have two circles joined together like this:
And I have a point inside the shape, and I would like to cast a ray in a direction from that point onto the shape. In order to retrieve the casted position on the edge of the shape.
My first thought will be to raycast with the 2 segments joining the 2 circles. And if there is no success hit, I'll raycast with the 2 circles and take the farthest hit position. Is there a better solution? More efficient computation-wise?
Thank you for your answers
Is suppose that you have direction vector of ray D=(dx, dy) and source point is inside of capsule
If you have central axis, use it's direction vector A, otherwise get direction vector S, S of any segment.
At first decide what segment might be intersected: get cross product A x D or S x Dand look at it's sign. Positive sign denotes that you have to check only intersection with the "left" segment, negative one - intersection with the "right" segment.

2D: Find the angle between mouse position and gameObject

I have a beer bottle positioned at top of a glass at 90%. I want to rotate it around its Pivot which is at the top. In order to do so i'm trying to find the angle between the the mouseposition(mp) and the bottle and rotate ti by it.
The center of rotation is the current position of the GameObject since the Pivot of the sprite is at the top. I tried to find two Vectors one being the vector from mp to center of rotation and the other one being the position of the bottle. Then i used: gameObject.transform.Rotate(Vector3.Forward, Vector3.Angle(v2,v1)).
The result its not what i expected of course. I'm new to this game math, i'd appreciate an explanation.
(Its an android game and i intend to drag the bottle up and down from 90 to 180 degrees).
I hope that i understand you question correctly.
But if you want to find the angle between the mouse point you can use the two lines you have drawn on the picture and just calculate the angle between them.
Check out this answer:
Calculating the angle between two lines without having to calculate the slope? (Java)

Efficient approximation of rotation

I am trying to write an algorithm that rotates one square around its centre in 2D until it matches or is "close enough" to the rotated square which started in the same position, is the same size and has the same centre. Which is fairly easy.
However the corners of the square need to match up, thus to get a match the top right corner of the square to rotate must be close enough to what was originally the top right corner of the rotated square.
I am trying to make this as efficient as possible, so if the closeness of the two squares based on the above criteria gets worse I know I need to try and rotate back in the opposite direction.
I have already written the methods to rotate the squares, and test how close they are to one another
My main problem is how should I change the amount to rotate on each iteration based on how close I get
E.g. If the current measurement is closer than the previous, halve the angle and go in the same direction otherwise double the angle and rotate in the opposite direction?
However I don't think this is quite a poor solution in terms of efficiency.
Any ideas would be much appreciated.
How about this scheme:
Rotate in 0, 90, 180, 270 angle (note that there are efficient algorithm for these special rotations than the generic rotation); compare each of them to find the quadrant you need to be searching for. In other word, try to find the two axis with the highest match.
Then do a binary search, for example when you determined that your rotated square is in the 90-180 quadrant, then partition the search area into two octants: 90-135 and 135-180. Rotate by 90+45/2 and 180-45/2 and compare. If the 90+45/2 rotation have higher match value than the 180-45/2, then continue searching in the 90-135 octant, otherwise continue searching in the 135-180 octant. Lather, Rinse, Repeat.
Each time in the recursion, you do this:
partition the search space into two orthants (if the search space is from A to B, then the first orthant is A + (A + B) / 2 and the second orthant is B - (A + B) / 2)
check the left orthant: rotate by A + (A + B) / 4. Compare.
check the right orthant: rotate by B - (A + B) / 4. Compare.
Adjust the search space, either to left orthant or the right orthant based on whether the left or right one is have higher match value.
Another scheme I can think of is, instead of trying to rotate and search, you try to locate the "corners" of the rotated image.
If your image does not contain any transparencies, then there are four points located at sqrt(width^2+height^2) away from the center, whose color are exactly the same as the corners of the unrotated image. This will limit the number of rotations you will need to search in.
...also, to build upon the other suggestions here, remember that for any rectangle you rotate around its center, you only need to calculate the rotation of a single corner. You can infer the other three corners by adding or substracting the same offset that you calculated to get the first corner. This should speed up your calculations a bit (assuming [but not thinking] that this is a bottleneck here).

Sliding AABB collision - getting stuck on edges

I'm working on a 3D tile based game and I'm using AABB collision detection. For every cube that the player is intersecting, I find the axis along which the player is intersecting the cube the least, and push the player out of the cube along that axis.
Depending on the order that the cubes are checked in, this can cause problems when sliding along the edge of multiple cubes. I have created a diagram that should explain the problem:
http://imgur.com/mmK0W.png
Arrow #1 is the attempted movement of the player. The other arrows are the collision response.
In the left diagram, collision is tested against the right cube first, causing the player to be pushed to the left, and then upwards. (bad)
In the right diagram, collision is tested against the left cube first, causing the player to be pushed upwards, at which point the player is no longer intersecting the other cube. (good)
Any ideas on what the most efficient way to solve this might be? Or any better ways to handle the collision response?
Thank you.
A discrete implementation forces you to inject some continuous math in the system, only when required (cubes / directions overlap).
For each cube c1, c2 ... ci with which the user cube (uc) intersects at the time of the check, you want to find out which cube was "touched" first - there is only one, as in real life. Consider the direction d of uc, and, taking the amount of uc in ci (overlapping) find the position of cu at the time it "touched" ci.
Determine which cube was "touched" first cj (the one that required the most rollback on the d axis - the sooner in time) and use only this one to calculate the collision reaction.
Not only you'll reach accuracy. but it will help if all cubes are moving, have different speeds etc...
From your diagram, it seems you want the smallest move that minimises the overlap between the player and the cubes. Each cube with overlap will try to "push" the player in two orthogonal directions. Can you do something like pick the minimum push of the maximum pushes in each direction?
You might implement a kind of hybrid broad phase when your two (or more) stationary cubes in a row can be combined into one larger rectangle. Test against the larger rectangle first. It will give you the results of your green check mark and be faster than checking each cube anyway. Then, after that, only if you need to, check against the individual cubes.
A collision can push an object on 1 axis only. To determine the axis to push:
else -- not this
elseif -- change to this
if w > h then
push x
elseif h > w then
push y
end
This works if your tiles are aligned.
Use circles to avoid the stick on unaligned tiles

Resources