i'm creating an android app(top-down shooter) on libgdx and have a problem with bullet positioning(No, with math for real)
So the problem is calculating a position of bullet
I want to spawn bullet here:
example
(where the red line is)
I calculating a position as:
bullet.setPosition(world.getPlayer().getX() + world.getPlayer().getWidth() * (float) Math.cos(Math.toRadians(world.getPlayer().getRotation())),
world.getPlayer().getY() + world.getPlayer().getHeight() * (float) Math.sin(Math.toRadians(world.getPlayer().getRotation())));
And it works well while rotation = 0, but as soon as i start to rotate my player it goes wrong :(
I am assuming that your player object is a libGDX Sprite. Therefore, the getX and getY are the coordinates of the bottom-left corner of the sprite and the getRotation is the rotation of the sprite about the origin (assumed to be at the centre of the player).
By doing some basic trigonometry you can convert the angle and a displacement to an (x,y) coordinate as you have attempted. The bullet needs to be rotated about the centre of the player. This can be done with the following code:
Sprite player = world.getPlayer(); //Just to tidy up the code
//Half width, half height and rotation
float hw = player.getWidth() / 2.0f;
float hh = player.getHeight() / 2.0f;
float rot = Math.toRadians(player.getRotation());
bullet.setPosition(player.getX() + hw + hw * (float) Math.cos(rot),
player.getY() + hh + hh * (float) Math.sin(rot));
Related
I am attempting to create an application that draws Fibonacci Arcs similar to these.
However, I'd like full circles instead of arcs, and I'd like to draw more than the three Fibonacci lines shown in the picture. I've created an application using JFreeChart to attempt to accomplish this. However, here is the result when trying to draw the same arcs (but as circles) shown in the previous picture.
Initially, it just looks wrong, but when I zoom out, it is indeed a circle, but it's way too big.
To calculate the arcs, you draw a line, then take a Fibonacci ratio - let's use .381 for example - the percentage of that line. If you look at the first picture, you'll see the innermost arc intersects the line at .381% the distance of the line from the centre of the circle. First I calculate this point. Then I construct a line from the .381% point to the centre. Then I take the distance of this line, which should be the radius. Then I use this radius to draw the circle.
Here's the code to calculate the radius. Where stop and start are the stop and start points of the line drawn.
multiplier = ratio38Value + i;
diffx = (stop.getX() - start.getX()) * multiplier;
diffy = (stop.getY() - start.getY()) * multiplier;
xValue = start.getX() + diffx;
yValue = start.getY() + diffy;
point = new Point(xValue, yValue);
lineSegment = new Line(point, stop);
radius = lineSegment.getDistance();
circle = new Circle(stop.getX(), stop.getY(), radius);
circles.add(circle);
Here is the code to calculate the distance of a line
public double getDistance(){
double x = Math.pow(endPoint.getX() - startPoint.getX(), 2);
double y = Math.pow(endPoint.getY() - startPoint.getY(), 2);
return Math.sqrt(x + y);
}
I get back a list of circle objects (this is an object I created that holds the radius and centre point) one for each circle that needs to be drawn and then draw them.
List<Circle> circles = fibonacciCalculations.getFibonacciArcs(startPoint, endPoint);
if(circles != null)
{
for (Circle circle : circles){
double xCenter = circle.getX();
double yCenter = circle.getY();
double radius = circle.getRadius();
plot.addAnnotation(new XYShapeAnnotation(new Ellipse2D.Double(xCenter - radius, yCenter - radius, radius + radius, radius + radius)));
}
}
I think the issue has something to do with how the x-axis of time and the y axis of price doesn't exactly correlate. What I mean is, if the radius is 20, you'll be going 20 units away from the centre at each point. So say you're stock price is only 5 dollars, at your lowest point you will then be at -15. If that is the case, I have no idea how to fix it. But it also could be some error in my logic. Any ideas would be appreciated.
EDIT: While the bars look like they may be weekly bars in the first picture, they are indeed daily bars. Also, I have already converted the coordinates from data space to x y coordinates. I use this code below to do that.
#Override
public void chartMouseMoved(ChartMouseEvent event) {
Rectangle2D dataArea = cp.getScreenDataArea();
JFreeChart chart = event.getChart();
XYPlot plot = (XYPlot) chart.getPlot();
ValueAxis xAxis = plot.getDomainAxis();
ValueAxis yAxis = plot.getRangeAxis();
double x = xAxis.java2DToValue(event.getTrigger().getX(), dataArea,
RectangleEdge.BOTTOM);
double y = yAxis.java2DToValue(event.getTrigger().getY(), dataArea,
RectangleEdge.LEFT);
I'm not sure of the proper terminology, so lets call the actual (x,y) coordinates that represent where you are on your monitor "screen space" and let's call the (x,y) coordinates of the chart "chart space".
My issue was I was converting the points from screen space to chart space and then calculating my points. Instead, I should have calculated all my points in screen space, and then converted each calculated point to chart space.
Where i is the amount of groups of arcs I want to draw. (i = 0, then I am drawing circles for the 38, 50, 62 ratios, i = 1 then I'm drawing circles for the -1.68, -1.50...1.50, 1.68 ratios) I use this code to get my points that are a given ratio between the center and the starting point.
multiplier = ratio62Value + i;
diffx = (stop.getX() - start.getX()) * multiplier;
diffy = (stop.getY() - start.getY()) * multiplier;
xValue = start.getX() + diffx;
yValue = start.getY() + diffy;
point = new Point(xValue, yValue);
line = new Line(point, stop);
line.calculateCirclePoints();
Here is the method to calculate the points on the circle. Where, endPoint is the center point, and the radius is the distance from the start point to the end point.
public void calculateCirclePoints(){
double radius = getDistance();
double radians;
double x;
double y;
Point currentPoint;
for (int degrees = 0; degrees <= 360; degrees += 1){
radians = Math.toRadians(degrees);
x = endPoint.getX() + (radius * Math.cos(radians));
y = endPoint.getY() + (radius * Math.sin(radians));
currentPoint = new Point(x, y);
points.add(currentPoint);
}
}
Lastly, I convert all of these points to chart space, and draw them on the chart.
public static Point converPointTo2D(Point point, Rectangle2D dataArea, XYPlot plot){
double x;
double y;
CustomNumberAxis xAxis = (CustomNumberAxis) plot.getDomainAxis();
CustomNumberAxis yAxis = (CustomNumberAxis) plot.getRangeAxis();
x = xAxis.java2DToValue(point.getX(), dataArea,
RectangleEdge.BOTTOM);
y = yAxis.java2DToValue(point.getY(), dataArea,
RectangleEdge.RIGHT);
return new Point(x, y);
}
One point to note, the radius of the circles is dependent on how much of a specific chart you're showing. A circle drawn on a 1 year chart from point a to point b will be smaller than a circle drawn on a 5 year chart from those same points.
I have a camera that has X, Y and Z Coordinates.
The camera also has a Yaw and a pitch.
int cameraX = Camera.getX();
int cameraY = Camera.getY();
int cameraZ = Camera.getZ();
int cameraYaw = Camera.getYaw();
int cameraPitch = Camera.getPitch();
The yaw has 2048 units in 360 degrees, so at 160 degrees the getYaw() method will return 1024.
Currently I move the camera forward by just setting the Y + 1 in each loop.
Camera.setY(Camera.getY() + 1);
How would I set the camera X and Y to the direction I'm facing (The Yaw)?
I don't want to use the pitch in this situation, just the Yaw.
If I understand your question correctly, you're trying to get the camera to move in the direction you're looking (in 2D space, you're only moving horizontally).
I made a small LookAt header-only library for C++, but here is part of it rewritten in Java. What this code does is it takes a rotation and a distance, then calculates how far you need to move (in both the x and y coordinate) to get there.
// Returns how far you need to move in X and Y to get to where you're looking
// Rotation is in degrees, distance is how far you want to move
public static double PolarToCartesianX(double rotation, double distance) {
return distance * Math.cos(rotation * (Math.PI / 180.0D));
}
public static double PolarToCartesianY(double rotation, double distance) {
return distance * Math.sin(rotation * (Math.PI / 180.0D));
}
I need to draw a spider using the Graphics package. The problem though is that its size, number of legs and eyes are specified by the user.
I've got a few questions:
how can I randomly select a point on a circle so I can draw a line (for legs) from there while keeping in mind that drawLine(), for instance, takes only integer arguments?
how can I randomly select a point inside the circle used as a center of an eye so that the circle (eye) fits within the ranges of an outer circle (body)?
Selecting a point on a circle just requires getting a random angle. Java uses radians for it's trigonometric functions so a random double between 0 and 1 is multiplied by 2π.
Random r = new Random();
double angle = r.nextDouble() * Math.PI * 2;
Drawing legs is simple trigonometry which requires finding the x and y of each line. For this sine and cosine functions are used. The line can then be drawn off the center point of the circle (centerX and centerY), ending at a specified length in pixels (legLength).
The process can be repeated to draw multiple legs with a specified offset (legOffset) and repeated and offset again (by π) to draw legs on the other side.
for (int i = 0; i < 4; i++) {
int lineX = (int) radius * Math.cos(angle);
int lineY = (int) radius * Math.sin(angle));
g.drawLine(circleX + lineX , circleY + lineY , circleX + lineX * legLength, circleY + lineY * legLength);
angle += legOffset;
}
Drawing the eyes is essentially the same process as the legs. Each eye can drawn at a specified angle and distance from the center of the circle.
int eyeX = (int) distance * Math.cos(angle);
int eyeY = (int) distance * Math.sin(angle));
g.fillOval(eyeX - eyeRadius, eyeY - eyeRadius, eyeRadius* 2, eyeRadius* 2);
The easiest way to get random integers is to create an instance of Random and with random.nextInt(bound) you get an integer between 0 (inclusive) and bound (exclusive), [0, bound).
Instead of selecting the upper left corner of the spider, I would randomly select the center of the spider and then draw everything in relation to it.
Now let's define the radius r = size / 2.
Selecting a random point with insuring that the spider is fully visible:
x = r + random.nextInt(width - 2 * r);
y = r + random.nextInt(height - 2 * r);
Drawing the body with a diameter of r and not 2r to ensure the legs are visible: g.fillOval(x - r / 2, y - r / 2, r, r);
Drawing the legs and eyes: There are numerous strategies, you could draw lines from the center with length r for the legs and very small circles at distance r/4 from the center for the eyes. After selecting an initial random angle, you can use the golden angle to calculate the position of the next leg / eye, this ensures they are never drawn at the same positon (https://en.wikipedia.org/wiki/Golden_angle).
Note: draw the legs first, then the body and the eyes last.
Problem
I'd like to calculate the origin of a bullet which comes out of turret barrels which aren't at the center of the turret.
Current Situation
I have a turret with a center barrel which can shoot bullets from it. The turret is at the vector location and as a varying angle, i. e. it keeps rotating. In order to make the center turret shoot bullets from the end of the barrel I calculate the end of it like this:
double speed = 1;
double angle = turret.angle;
// start at the end of the barrel
double x = turret.location.x + Math.cos( angle) * turret.centerCannonLength;
double y = turret.location.y + Math.sin( angle) * turret.centerCannonLength;
// calculate angle and velocity of bullets
double dx = Math.cos(angle) * speed;
double dy = Math.sin(angle) * speed;
from that I can set the initial location and the velocity of the bullets with this:
Bullet bullet = new Bullet();
bullet.setLocation( x, y);
bullet.setVelocity( dx, dy);
bullet.setAngle( angle);
Task
Now I'd like to have 2 additional barrels from which the turret can fire. The barrels aren't in the center, they are offset left and right.
Question
How do I calculate the origin of the bullets from the left and right barrel?
Here's a demo screenshot:
The blue circle describes the rotation of the turret. The yellow parts are the turret and the center barrel. The red parts are the additional left and right barrels of which I'd like to calculate the bullet origin position.
Thank you very much for the help!
First, define the location of the origin in the turret's local coordinate space. The center barrel would be:
localX = turret.centerCannonLength
localY = 0
Then, find the current rotation matrix of the turret:
M = / cos(angle) -sin(angle) \
\ sin(angle) cos(angle) /
And multiply this matrix with the local position:
globalX = turret.location.x + cos(angle) * localX - sin(angle) * localY
globalY = turret.location.y + sin(angle) * localX + cos(angle) * localY
I'm trying to find the angle of a circle(2d) where I intersect with another (2d)object
I have a spaceship and a planet, I know what the X and Y coordinates are of both.
Now i need to know what the angle/degree is of the planet WHERE the spaceship intersected with the planet.
Thanks in advance.
,Cheers
Ozcan
If the origin is at (0, 0), the angle (in radians) would be calculated like this:
int deltaX = planet.centerX - spaceship.centerX;
int deltaY = planet.centerY - spaceship.centerY;
double radians = Math.atan2(deltaY, deltaX);