I want my player rotate towards mouse. Here's the code calculating the angle:
float angle = (float) Math.atan2(MouseInput.getMousePos().y - transform.position.y + transform.size.y / 2,
MouseInput.getMousePos().x - transform.position.x + transform.size.x / 2);
angle = (float) (angle * (180 / Math.PI));
if (angle < 0) {
angle = 360 + angle;
}
transform.rotation = 180 + angle;
And getMousePos() method (it just returns mouse pos relative to window):
public static Vector2 getMousePos() {
Point p = MouseInfo.getPointerInfo().getLocation();
return new Vector2(p.x - Game.w.getAccessToWindow(Acces.WINDOW_JFRAME_ACCES).getLocation().x,
p.y - Game.w.getAccessToWindow(Acces.WINDOW_JFRAME_ACCES).getLocation().y);
}
Can you tell me what's wrong with this code? Player isn't rotating properly.
I tried following this article: https://gamefromscratch.com/gamedev-math-recipes-rotating-to-face-a-point/
Update:
I found this post: Java 2d rotation in direction mouse point
Now I've updated my code to this:
int centerX = (int) (transform.size.x / 2);
int centerY = (int) (transform.size.x / 2);
int mouseX = (int) MouseInput.getMousePos().x;
int mouseY = (int) MouseInput.getMousePos().y;
double angle = Math.atan2(centerY - mouseY, centerX - mouseX) - Math.PI / 2;
transform.rotation = angle;
But still something is off. Try this code for yourself. Maybe I did something wrong somewhere else.
i'm struggling to word the question a little but I am essentially making a game in which the user will have a limited field of view, the game itself is top down but the player will have to interpret their surroundings based off of the interaction of their small field of view and the walls.
I have created the system for the raysy to be created, however I am struggling to work out the math behind, as well as the implementation of making the angle at which my rays come out of be relevant to the mouse position
code:
private LinkedList<Line2D.Float> calcRays(LinkedList<Line2D.Float> lines, int x, int y, int resolution, int maxDist){
LinkedList<Line2D.Float> rays = new LinkedList<>();
//field of view affected by i
for(int i = 0 ; i < resolution; i++) {
float angle = (float) Math.atan2(mosy - player.getY(), mosx - player.getX());
double dir = (Math.PI*2) * (double) i / resolution / 15;
float minDist = maxDist;
for(Line2D.Float line : lines) {
float dist = getRayCast(x, y, (player.getX()+16)+(float) Math.cos(dir) * maxDist, (player.getY()+16)+(float) Math.sin(dir) * maxDist, line.x1, line.y2, line.x2, line.y2);
if(dist < minDist && dist > 0) {
minDist = dist;
}
}
rays.add(new Line2D.Float(x, y, (player.getX()+16)+(float) Math.cos(dir) * minDist, (player.getY()+16)+(float) Math.sin(dir) * minDist));
}
return rays;
}
public static float dist(float x1, float y1, float x2, float y2) {
return (float) Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
public static float getRayCast(float p0_x, float p0_y, float p1_x, float p1_y, float p2_x, float p2_y, float p3_x, float p3_y) {
float s1_x, s1_y, s2_x, s2_y;
s1_x = p1_x - p0_x;
s1_y = p1_y - p0_y;
s2_x = p3_x - p2_x;
s2_y = p3_y - p2_y;
float s, t;
s = (-s1_y * (p0_x - p2_x) + s1_x * (p0_y - p2_y)) / (-s2_x * s1_y + s1_x * s2_y);
t = (s2_x * (p0_y - p2_y) - s2_y * (p0_x - p2_x)) / (-s2_x * s1_y + s1_x * s2_y);
if (s >= 0 && s <= 1 && t >= 0 && t <= 1) {
// Collision detected
float x = p0_x + (t * s1_x);
float y = p0_y + (t * s1_y);
return dist(p0_x, p0_y, x, y);
}
return -1; // No collision
}
This is all of the code related to calculating the ray casts, if anyone would be able to show me how I can add this feature i'd be extremely grateful.
Thanks
I am trying to draw a certain type of polygon but i can't manage to get it to work. Are my formula wrong ? And if so, can you help me?
I want to draw a polygon using Java.awt.polygon
TMP = new Polygon();
// this.getX() and this.getY() return an int
// consider getX() and getY() as x0 and y0
int x1,x2,x3,x4;
int y1,y2,y3,y4;
x1 = (int) Math.round(this.getX() - this.getLength() * Math.cos(this.getAngle()));
y1 = (int) Math.round(this.getY() - this.getLength() * Math.sin(this.getAngle()));
x3 = (int) Math.round(x1 - this.getWidth() * Math.cos((Math.PI / 2) - this.getAngle()));
y3 = (int) Math.round(y1 + this.getWidth() * Math.sin((Math.PI/2) - this.getAngle()));
x4 = (int) Math.round(this.getX() - this.getWidth() * Math.cos((Math.PI/2) - this.getAngle()));
y4 = (int) Math.round(this.getX() + this.getWidth() * Math.sin((Math.PI/2) - this.getAngle()));
x2 = (int) Math.round((x1 + x3) / 2 + Math.cos(this.getAngle()) * this.getLength() / 2);
y2 = (int) Math.round((y1 + y3) / 2 + Math.sin(this.getAngle()) * this.getLength() / 2);
TMP.addPoint(this.getX(), this.getY());
TMP.addPoint(x1, y1);
TMP.addPoint(x2, y2);
TMP.addPoint(x3, y3);
TMP.addPoint(x4, y4);
this.setPolygon(TMP);
This is what i expect
https://i.gyazo.com/bdd8510d0128bab6347bb6c110f03c92.png
And i'm getting this
https://i.gyazo.com/55a00ae07d4f31732db12805fa592aec.png
My formulas were right. My values for length and widths were incorrect. My width was my length and mylength was my width. Sorry!
I wrote a little program which draws a circular chromatic gradation using Andres' algorithm.
Here is the result of an execution :
If the final-user gives the program a shift, in radians, it will use the latter to begin the drawing of the circle at this angle. Thus, the gradation will begin at this angle (and that's what I want).
For example, you can see that the gradation begins at the bottom of the circle and not at its left in the following image.
But as you can see, two problems appear :
First, there are some gaps in the circle ;
Then, the circumference of the circle is quite imprecise.
I think it's a problem of precision. So I asked myself if there were some bad casts but it's not the case.
Well, I don't know what is the reason why my circle is so imprecise. Could you help me please ?
Here is the class that draws each pixel of the circle. It takes on board the specified shift, in radians.
/**
* Constructs a Pixel taking account of a shift and near the position (x0 ; y0)
* #param x
* #param y
* #param color
* #param angle
* #param x0
* #param y0
*/
Pixel(double x, double y, Color color, double angle, double x0, double y0) {
this.x = (int) (x0 + (x-x0) * Math.cos(angle) - (y-y0) * Math.sin(angle));
this.y = (int) (y0 + (y-y0) * Math.cos(angle) + (x-x0) * Math.sin(angle));
this.color = color;
}
Now, the code that draws the circle, using Andres' algorithm and the Pixel class.
case "Andres' algorithm":
w = 2 * Math.PI;
for(double current_thickness = 0; current_thickness < this.thickness; current_thickness++) {
x = 0;
y = (int) (radius + current_thickness);
double d = radius + current_thickness - 1;
while (y >= x) {
double octant_1_x = x0 + x, octant_1_y = y0 + y;
double octant_2_x = x0 + y, octant_2_y = y0 + x;
double octant_3_x = x0 - x, octant_3_y = y0 + y;
double octant_4_x = x0 - y, octant_4_y = y0 + x;
double octant_5_x = x0 + x, octant_5_y = y0 - y;
double octant_6_x = x0 + y, octant_6_y = y0 - x;
double octant_7_x = x0 - x, octant_7_y = y0 - y;
double octant_8_x = x0 - y, octant_8_y = y0 - x;
max_counter++;
double[] rgb_gradation_octant_1 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_1_y - y0, octant_1_x - x0) + Math.PI, w);
updates.add(new Pixel(octant_1_x, octant_1_y,
Color.color(rgb_gradation_octant_1[0], rgb_gradation_octant_1[1], rgb_gradation_octant_1[2]),
circle_gradation_beginning, x0, y0)); // octant n°1
double[] rgb_gradation_octant_2 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_2_y - y0, octant_2_x - x0) + Math.PI, w);
updates.add(new Pixel(octant_2_x, octant_2_y,
Color.color(rgb_gradation_octant_2[0], rgb_gradation_octant_2[1], rgb_gradation_octant_2[2]),
circle_gradation_beginning, x0, y0));
double[] rgb_gradation_octant_3 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_3_y - y0, octant_3_x - x0) + Math.PI, w);
updates.add(new Pixel(octant_3_x, octant_3_y,
Color.color(rgb_gradation_octant_3[0], rgb_gradation_octant_3[1], rgb_gradation_octant_3[2]),
circle_gradation_beginning, x0, y0));
double[] rgb_gradation_octant_4 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_4_y - y0, octant_4_x - x0) + Math.PI, w);
updates.add(new Pixel(octant_4_x, octant_4_y,
Color.color(rgb_gradation_octant_4[0], rgb_gradation_octant_4[1], rgb_gradation_octant_4[2]),
circle_gradation_beginning, x0, y0)); // octant n°4
double[] rgb_gradation_octant_5 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_5_y-y0, octant_5_x-x0) + Math.PI, w);
updates.add(new Pixel(octant_5_x, octant_5_y,
Color.color(rgb_gradation_octant_5[0], rgb_gradation_octant_5[1], rgb_gradation_octant_5[2]),
circle_gradation_beginning, x0, y0)); // octant n°5
double[] rgb_gradation_octant_6 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_6_y-y0, octant_6_x-x0) + Math.PI, w);
updates.add(new Pixel(octant_6_x, octant_6_y,
Color.color(rgb_gradation_octant_6[0], rgb_gradation_octant_6[1], rgb_gradation_octant_6[2]),
circle_gradation_beginning, x0, y0));
double[] rgb_gradation_octant_7 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_7_y-y0, octant_7_x-x0) + Math.PI, w);
updates.add(new Pixel(octant_7_x, octant_7_y,
Color.color(rgb_gradation_octant_7[0], rgb_gradation_octant_7[1], rgb_gradation_octant_7[2]),
circle_gradation_beginning, x0, y0));
double[] rgb_gradation_octant_8 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_8_y-y0, octant_8_x-x0) + Math.PI, w);
updates.add(new Pixel(octant_8_x, octant_8_y,
Color.color(rgb_gradation_octant_8[0], rgb_gradation_octant_8[1], rgb_gradation_octant_8[2]),
circle_gradation_beginning, x0, y0)); // octant n°8
if (d >= 2 * x) {
d -= 2 * x + 1;
x++;
} else if (d < 2 * (radius + thickness - y)) {
d += 2 * y - 1;
y--;
} else {
d += 2 * (y - x - 1);
y--;
x++;
}
}
}
gui.getImageAnimation().setMax(max_counter*8);
break;
you don't have to 'rotate' the pixel, you just have to draw them
Pixel(double x, double y, Color color, double angle, double x0, double y0) {
this.x = (int) (x + x0);
this.y = (int) (y + y0);
this.color = getColorForAngle(angle);
}
Bresenham / Andres provide all pixels of the circle, no need to translate/rotate them
I am drawing a triangle on canvas:
float x = 540;
float y = 960;
Path path = new Path();
path.moveTo(x, y);
path.lineTo(x+18, y+60);
path.lineTo(x-18, y+60);
path.lineTo(x, y);
canvas.drawPath(path, mPaint);
This canvas has another objects. But I need to rotate only this triangle around center of this triangle on a random angle (between 0 and 360). How to implement it? How to get coordinates vertexes of a triangle after rotation?
Its simple math, if the center of the triangle is (x,y) and the center-vertex distace is A, the three vertex will be
-(A*Math.cos(angle),A*Math.sin(angle))
-(A*Math.cos(angle+2*Math.PI/3),A*Math.sin(angle+2*Math.PI/3))
-(A*Math.cos(angle-2*Math.PI/3),A*Math.sin(angle-2*Math.PI/3))
I solve it by this way:
float angle = (float) Math.toRadians(90); // Angle to rotate
// Size of triangle
final float height = 60;
final float width = 36;
// Display coordinates where triangle will be drawn
float centerX = 540;
float centerY = 960;
// Vertex's coordinates before rotating
float x1 = centerX;
float y1 = centerY - height / 2;
float x2 = centerX + width / 2;
float y2 = centerY + height / 2;
float x3 = centerX - width / 2;
float y3 = y2;
// Rotating
float x1r = (float) ((x1 - centerX) * Math.cos(angle) - (y1 - centerY) * Math.sin(angle) + centerX);
float y1r = (float) ((x1 - centerX) * Math.sin(angle) + (y1 - centerY) * Math.cos(angle) + centerY);
float x2r = (float) ((x2 - centerX) * Math.cos(angle) - (y2 - centerY) * Math.sin(angle) + centerX);
float y2r = (float) ((x2 - centerX) * Math.sin(angle) + (y2 - centerY) * Math.cos(angle) + centerY);
float x3r = (float) ((x3 - centerX) * Math.cos(angle) - (y3 - centerY) * Math.sin(angle) + centerX);
float y3r = (float) ((x3 - centerX) * Math.sin(angle) + (y3 - centerY) * Math.cos(angle) + centerY);
// Drawing
Path path = new Path();
path.moveTo(x1r, y1r);
path.lineTo(x2r, y2r);
path.lineTo(x3r, y3r);
path.lineTo(x1r, y1r);
canvas.drawPath(path, mPaint);
Thanks to Gimka and Nofate for help.