Java Angle Math: Check how near the player looks to object - java

I am programming a Minecraft Bukkit plugin and need a way to calculate an input number from 0 to 360 for displaying a custom compass. So if the player directly looks at the object (shouldn't handle viewing height or position height), this number would be 0 and if the player's back is looking on the object it would be 180.
I already successfully calculated both numbers I need:
The absolute looking angle of the player. Is 0 when the player looks in north direction and 180 in south direction.
The location angle between the player's position and the object's position. Using Math.atan2 to get the angle between [X, Z] of these locations.
Both values seems to be calculated correctly. But I can't find out what to do to get the number I described at first. Tried substraction, addition. Any ideas?

It should be the difference between them - if the player is looking north, and the object delta x, delta z gives a bearing of 45 degrees then the needle should be in front and to the right at 45 (=45-0), if the player is looking south and tho object x,z is 45 then the needle should be behind and to the left at 225 or -135 (=45-180).
Check that you've converted the result of Math.atan2 to degrees so you're subtracting values in the same units, and that the axes conventions are consistent. This says that +ve x-axis is east and +ve z-axis is south. A bearing of 0, North is given by atan2(0,1), which implies that you should be using Math.toDegrees(Math.atan2(deltaX, -deltaZ)) to get the bearing.
When doing these sort of things, it's much easier to write up half a dozen unit tests which cover the cases and play with the signs to see what the effects are.

Related

Only having the circle radio, loop the circumference coordinates (x, y)

I'm making my own Minecraft world border plugin for myself use.
I have a spawnpoint, that can be any coordinates, and I check the distance between player and the spawnpoint. If the distance exceeds 1000 (that is the radio) I cancel the user movement.
So I can say my circle radio is 1000.
The problem is: I want to draw in the world the circle borders, so the player can see the world borders. I need to iterate over the coordinates of the circumference, and I dont have any idea of how to do that (my maths are really poor)
Thanks you
Usually to iterate through the coordinates of a circe you want to use a bit of trigonometry.
You create a variable angle which starts from 0 and you iterate it by the step you need until 2π, then your x coordinate will bee cos(angle) and your y coordinate will be sin(angle).
Then probably you will have to round a bit those value considering you want to use them in a minecraft word where you can't place blocks in decimal coordinates

Java planetary orbit simulation: centering planets

I've created a simple planetary simulation where a planet orbits a star.
The code for the orbit is this:
a = a + vel * delta;
planetX = Math.cos(a) * orbitRadius + parentStar.getX();
planetY = Math.sin(a) * orbitRadius + parentStar.getY();
Now that works just fine, but my problem is that the orbit is not from the center of the planet around the center of the star.
This is what happens
As you can see, the first red dot on the small circle is the Position of the planet wich orbits around the second small red dot, this is because the circle is drawn from (0,0), so both the planets (0,0) circles around the (0,0) of the star.
I need the the center of the planet to circle the stars center, not their origin point.
Is there a good fix for this?
Your calculation of the orbit is fine. The only problem seems to be that you treat "position" differently when calculating orbits and when drawing the planets: When you draw them, you treat x and y as one of the corner points, but when you calculate the oribit, you treat them as the centre of the body. The simplest way would be to change the visualisation, not the calculation.
Since you did not post the code you use to draw the shapes, I can only guess, but I assume it looks somewhat like this (obviously Pseudocode):
for (Planet p : starsAndPlanets) {
drawCircle(p.x, p.y, p.radius * 2, p.radius * 2);
}
Change this to something like this:
for (Planet p : starsAndPlanets) {
drawCircle(p.x - p.radius, p.y - p.radius, p.radius * 2, p.radius * 2);
}
This way, x and y are the position of the centre of the planet, and with p.x - p.radius and p.y - p.radius you get the corner point. Of course, you could in a similar way change all your orbital mechanic formulas to calculate the centre from the corner point, but IMHO it is much simpler and more natural to treat x and y as the centre.
For now the most suitable way I can think of is getting the star's world coordnates and passing them every frame to the child's coordinates. As you do so, the child would have the same coordinates everyframe.
The next part is translating it and rotating it around the Star - the way you can achieve that is by setting the planet's position to be transposed by the Star's position with a sin(x)*cos(x).
Let me show you an example:
planet[0] = star[0] + sin(angle)*scale
planet[1] = star[1] + cos(angle)*scale
Where the angle would change incrementally and the scale will just shift the child object further from its parent, keeping it a constant (or modifying it if you wish) thus increasing the radius from its 'new' center.
I know some people may mention matrices or other types of transformations, but for this situation I think the above solution would be most relevant and cleanest in my opinionp
The way it works is you take the parent's 'WORLD coordinates' and set them to be the child's. By modifying the Scale value you increase the distance of the object from the center (so they won't overlap) and you multiply this with the sin and cos of the angle you specified to make it rotate.
P.S. Keep in mind that if you're dealing an FPS-dependant engine to render, the more FPS the faster the simulation will be, and vice-versa, because if you render at 1000 fps, this means you execute your code 1000 times, compared to 100 for example. Therefore, you will increment the angle 1000 times or 100 respectively. If you have this issue, try setting a constant framerate if you can - it's the simplest workaround for lightweight simulations.
Edit: I forgot to mention that the concept works for all objects in your case. You just have to work our the relationships and use the function for eqch object seperately where each object has a position and angle of orbit (if it orbits around a different object).

Pacman collision detection with varying character speeds?

I am programming a 2D, grid-based Pacman game. All the tiles are 8x8 in size. In-game, the map tiles are treated as 16x16, and the characters (Pacman and the ghosts) are treated as 32x32. In actuality, they are all pulled from a spritesheet of 8x8 tiles. I store positions as the center point of each character. Since the character tiles are bigger than the map tiles, the map is built in a way that requires the characters being able to "overlap" onto blocked tiles.
To deal with this set of problems, I created an invisible Rectangle and attached it to the character's position. Where the position is an (x,y) point, the Rectangle is a box surrounding that point. This rectangle is essentially 16x16 in-game, and is in the center of the character, which allows for the overlap necessary.
This works fine if you're working with 8px as the global movement speed, but I'd like to treat 8px as "100% speed" and have complete control over character speed with a double that is in the range [0,1). The positions are stored as double points, so on that level, this is fine. I read the positions back as integers, though, since I'm working with pixels.
So the question I ask is essentially "if this moves X amount of pixels to direction Y now, will my collision box be touching a blocked tile? But if you're moving 5px at a time, this eventually causes a very obvious issue. Say you're at x = 0, moving right. The tiles are 16x16 in-game, as stated before, and you have two of these open before the third, which is blocked. So you move, x = 5, x = 10, x = 15, x = 20, we just got to the 2nd tile, x = 25, x = 30, x = 35 now we're in the 3rd tile... but wait. We can't go there, because X = 35 collides. And unfortunately, we needed to turn and start moving down, but we can't, because now our Y-axis isn't aligned properly with the grid. Our X position needs to be 32, but can't.
My question for everyone here is, what are my options? What are some ideas or insights you have? I have a feeling I'm making it more difficult than I need to.
sounds like you have...
Why not give your "pac-man" sprite a velocity vector? The vector will describe not only the speed at which "pac-man" is traveling but in what direction, meaning you can see ahead.
"pac-man" should be calculating and ultimately making a decision based upon the following conversation..."hey, moving at this speed and in this direction..in so many seconds I'm going to hit a wall, when does that happen?". The seconds don't even have to be seconds...they could be "squares".
You would need a function which takes in the initial movement vector (direction and speed) which returns a coordinate of an X,Y point where "pac-man" must stop, where he cannot go further and must change direction (the center of a tile adjacent to a wall). Each time "pac-man" changes direction, run this calculation again...you do not need to keep checking if the next square is passable. If his direction hasn't changed and his speed is constant..you only need calculate once and let the coordinate system do the rest.
With this approach, square size and velocity is irrelevant...until "pac-man" hits or within his next movement exceeds the stopping point, continue to move along the vector.

Tetrahedron Java3d

As describes the Methane image, I need to make a Tetrahedron in Java3d with the angles between any two bounds to be 109 deg (H are bounded with C, so the lines are the bounds).
I must admit that I don't quite have any idea about how should I do it. I tried it that way: one bound with rotX and rotZ at 0 deg both. The one rotX at 109 deg. The next step would be rotZ and rotX at 109 deg. Let's say that angle for rotX is AngleX and the angle for rotZ is AngleZ. The end of my cylinder will be (calculated and tried) at (sin AngleZ,cos AngleZ*cos AngleX, cos AngleZ*sin AngleX). This is legit, so ouviously rotating again would do no good.
I have 4 cylinders of 2f length, created one at a time, translated at (0,1,0) so their end is at (0,0,0). From this point, I rotate my cylinders around the point (0,0,0) and I try to achieve a tetrahedron. The left cylinder is at {109,0} and the right one at {109,109} Can be easily seen that it's not the same angle between the left cylinder and the one going up and the right one and the cylinder going up
Also I have to say that solving this by calculus won't help me too much, because I will probably need to change angles in some situation, but I still need it to have same angles between cylinders.
Any ideas? How should I solve this?
Note: To be easier, I transformed from radians to degrees in my program so I work with degrees.
I think you may be making this a bit more complicated than it needs to be. Isn't methane symmetrical? If so, put the hydrogen atoms at non-adjacent vertices of a cube, and the carbon at the center of the cube.
To see what I mean do a Google search for "methane symmetry" and look at the images.
If you need a non-symmetrical variant, I would still calculate the locations of the atoms outside your program, or using non-graphical code, and only use java-3d to place them.

Coastline fractal proportions

I'm making a coastline fractal on a window that is one by one wide, and I would like to make the very first one pictured below, however, I cannot figure out which x and y coordinates to use to make the angles form 90 degrees and still fit on the screen, I don't need any code, I just would like how to figure out which x and y coordinates to use. Thanks!
Points:
1st point: (0,0.5)
2nd point: (0.25,0.75)
3rd point: (0.75,0)
4th point: (1,0.5)
My work (although messy and illegible at times):
It looks like from the picture that the first and last point both have a y-value of 0.5. Since the viewing window is one, you divide it into 4 parts each of which is 0.25 in length. The triangles that are formed if you draw a horizontal line at y=0.5 are isosceles according to the image. Thus, you solve: sin(45)=x/0.5.
re "x and y coordinates are doubles in between 0 and 1",
Then you will need to translate from your model (the set of points that make up your fractal) and the view (the GUI display). The model will go from 0 to 1, the view from 0 to the graphical window's width. A simple linear transformation where you multiply the model by some scale factor will serve.
Seems like you're wanting to map an abstract coordinate system to your screen.
Let's say your endpoints (in arbitrary coordinates) are (0, 0) and (1, 0). Then your points for the leftmost figure, in this system, will be (0, 0), (1/4, sqrt(2)/4), (1/2, 0), (3/4, -sqrt(2)/4), and (1, 0).
The other diagrams are calculated by some method. It sounded like your question was focusing on fitting it to the screen, so I'll continue with that. The method for fitting it to the screen is the same.
From there, you have a screen coordinate system. Each point is transformed to the screen. Let's say you have a 1000 by 1000 screen, with screen coordinates (0, 0) in the upper left. If you want to take up the entire screen, then you'd do the following:
Flip the y coordinates (+y is down on your screen)
Determine the full range in x and y for your arbitrary coordinates (1 for x, sqrt(2)/2 for y)
Multiply x values by 1000, and y values by 2000 / sqrt(2) to expand to the screen.
Subtract 500 from y values to center the image in the y direction.

Categories

Resources