# Solved Player direction facing location

Discussion in 'Spigot Plugin Development' started by xSwagyy, Jul 14, 2021.

1. ### xSwagyy

Okay, bare with me here, so lets say I have a player (A) and a certain point on the map (B),
so the point (B) is located at lets say for example, 100 60 -250 and the player (A) is located at -50 70 150.
So far so good, what I want, is to check what direction the player is supposed to be heading, for example, north.
I've tried a lot of stuff and couldn't get it to work. The idea is the player is standing there, and for example facing the direction south, while the point (B) is located north of the player, I want to check that, what direction the player needs to be heading as of his current location to the point. Hopefully I explained it good

Thanks in advance for anyone who helps

3. ### xSwagyy

I've looked at the thing, the only thing I understood is I need to subtract the vectors of the two locations, okay, done that, but still didn't tell me much as to how I'm supposed to get the cardinal direction

4. ### wand555

I answered a similar question a while ago.

In your case you're probably mainly interested in this method
Code (Java):
private static final double TIPPING_LIMIT = 0.5;

public Vector getClosestCardinalVectorFrom(Vector movedDir) {
Vector closest = null;
double lowestAmountChangedDir = -Double.MIN;
for(Vector cardinalVec : cardinalVectors) {
tempChangedDir = cardinalVec.dot(movedDir);
if(tempChangedDir >= TIPPING_LIMIT) return cardinalVec;
if(tempChangedDir > lowestAmountChangedDir) {
lowestAmountChangedDir = tempChangedDir;
closest = cardinalVec;
}
}
return closest;
}
though I suggest you check out my explanation in that post as well.
Feel free to ask if something is still unclear

5. ### xSwagyy

There are a lot of variables in that method that do not exists, for example, "tempChangedDir" and there is no such thing as "Double#MIN"
Any way you could maybe help me implement it into the code?
And is adding directions such as South East and North West a possibility?

6. ### wand555

I rarely write functioning code when explaining math (sorry, not sorry).
tempChangedDir is just missing the Vector type and Double.MIN represents the minimal value. Correct syntax would be Double.MIN_VALUE or Double.NEGATIVE_INFINITY.
That's totally fine, though you need to specify a bit more what you didn't understand so I can help you better.
Yes it should be. After thinking some minutes about it the only difference would be to change the tipping limit to 0.25

7. ### xSwagyy

Okay, I successfully implemented it, but I have two issues which are problematic.
First one is when its time for the direction to be flipped, for example I passed the point and it needs to point towards north, it still says south.
The second one, which is a bit more problematic, its very very CPU intensive, like 1% usage (server) to 14% usage (server), though that I could combat using delays between calculations, however a more efficient way may be more of use but I'll find a way to make it work.
I mainly need a way to fix the first issue where it always says the same direction.

8. ### wand555

Could you elaborate on that (perhaps show an example with coordinates)?
Yeah, the dot product computation is probably the most intensive operation. Each dot product requires 2 sqaure root computations, which are always not that cpu friendly.

9. ### xSwagyy

So I start tracking a certain point at: 14 78 -163
The point I'm tracking is: -8 72 -127, which is south of where I'm starting. so far so good.
However, if I go to another point, for example: 14 82 -57, which is after the point, the point that is being tracked is north of the location of the player, however the method still returns south.

I would've attached screenshots but I really have no idea how to visually explain it, but I'll try

10. ### Sigong

Are you calculating this on PlayerMoveEvent? If so, try instead putting the method in a repeating task that only runs once every second (20 ticks), and checking the most recent result of the 1 second task on the PlayerMoveEvent, instead of calculating it every time the event fires.
https://bukkit.fandom.com/wiki/Scheduler_Programming

• Like x 1
11. ### Maxx_Qc

Running it async is also an idea

12. ### xSwagyy

Yeah switching the event could be a good idea actually. I'll try that. anyways here is a visual (ish) representation of the first issue:
Point A is where I started, point C is the point that is tracked, and point B is the point after I started that still says that point C is south of it for some reason. (yes I know my Microsoft Whiteboard skills are not good sush.)

13. ### Sigong

This doesn't make sense to me, did you mix up B and C in the second sentence?

14. ### wand555

I'm failing to understand you.
The direction (north, south, etc.) is relative to the direction you're looking at (at the coordinates/points).
In your example my code actually produces the wrong result with south already, because C is North from point A (if you're not talking about head rotation).

15. ### xSwagyy

Yeah my bad, when I'm at point C it says that point B is still south of point C, which its in
fact north of it.

16. ### xSwagyy

Here is a visual in game:
The arrow points towards point B (tracked point) and I'm standing on point A.

And here I'm at point C, which is south of the tracked point (B) and it still says that point B is south, even though its north.

17. ### wand555

The facing is relative to the direction your looking at. If you turn around in the last picture it will say south. Are you passing in the player's direction or the location (as vector) into the method I gave you earlier?

18. ### wand555

No matter what you tried you also need to normalize the vectors before passing them to the method. I reconstructed your example (all coordinates scaled down by a factor of 10)
As you can see in the image the dot product (c and d) are below the threshold so they should stick with South ( (0, 1) as a 2d vector) as their closest cardinal direction.

19. ### xSwagyy

Okay, seems like normalizing them was the problem, though it still doesn't give me the correct direction in order to reach point B (tracked one).
Now it snaps correctly to the cardinal directions though instead of just showing south.
The input for the method:
Code (Java):
player.getLocation().getDirection().subtract(location.toVector()).normalize();
EDIT: That's the code that shows south ONLY
the code that gives me all the different directions depending on where I'm looking is this:
Code (Java):
player.getLocation().getDirection().subtract(location.getDirection()).normalize();

20. ### wand555

Try ignoring the players direction. I think I got now what you want. No matter where the player is looking, you want to tell them the direction they have to move in to reach the tracked point from their current point, right?
Code (Text):
player.getLocation().subtract(targetLoc).toVector().normalize()
should be the input for the method.