I'm trying to make a Brick Breaker game in Java and I want my ball to have a curved trajectory, based on paddle's acceleration (no gravity involved). How can I compute the ball position at a given moment? I think I need to compute the velocity first but i can't figure out how to do this.
The Spinning ball's path.
Curved trajectory? Do you mean when you hit the ball you add spin to the ball and then that spin causes the ball to curve through the air?
If so then use the following method.
The ball needs the following properties
ball = {
x, // position x, y
y,
dx, // delta x and y
dy,
dr, // delta rotation
radius, // balls radius
}
And a bat
bat = {
top, // y pos of top of bat
dx, // delta x (sideways speed
// plus what ever else you have
}
When the ball hits the bat do the normal reflection.
ball.dy = -ball.dy;
ball.y = bat.top - ball.radius
To convert the bats sideways movement into ball rotation just needs the ball's radius (for the most simple method) Assuming that the bat is at bottom of screen.
The amount of spin is related to the ball sideways motion relative to the bat, then divided by the radius to give the change in rotation per frame. Add that to the ball's current rotation
ball.dr += (ball.dx - bat.dx) / ball.radius
We are not going to do a full fluid dynamic simulation but rather an approximation.
Magnus effect
When a ball moving through the air, is spinning, one side of the ball moves forward in the air stream (outside), and the other side move in the opposite direction (inside). The imbalance in airflow over the surface and the way the inside spin pulls the air with it causes a low pressure region on the inside in the direction perpendicular to the ball's motion.
The force applied by this low pressure area is spread over the ball's diameter
Force = (airDensity * ballVelocity * Math.pow(2 * PI * ball.radius,2) * ball.dr ) / (2 * ball.radius)
We don't need all of this. Air density is fixed as is the ball radius. Thus the force is a linear relationship between ball velocity and ball spin rate. The rest can be set as a coefficient value we can call spinCof
The force adds acceleration which is dependent on mass. Again this does not change so we can add that to the spinCof value.
So the final formula is
Acceleration = spinCof * ballVelocity * ball.dr;
The value of spinCof is unknown and you will need to experiment to find a value that is playable.
To do this in code
spinCof = ? some value
var ballVelocity = Math.sqrt(ball.dx * ball.dx + ball.dy * ball.dy);
var nx = ball.dx / ballVelocity; // get normalised vector of motion
var ny = ball.dy / ballVelocity;
var accel = spinCof * ballVelocity * ball.dr; // get the acceleration due to spin
ball.dx -= ny * accel; // apply acceleration perpendicular to motion
ball.dy += nx * accel; //
And that is it.
And quick example of this in practice
var createImage=function(w,h){var i=document.createElement("canvas");i.width=w;i.height=h;i.ctx=i.getContext("2d");return i;}
// create canvas and add to DOM
var canvas = createImage(512,200);
var ctx = canvas.ctx;
document.body.appendChild(canvas);
var w = canvas.width;
var h = canvas.height;
const spinCof = 0.01;
const airFriction = 0.001;
const spinFriction = 0.001;
var ball = {
x : ctx.canvas.width * 2, // start off screen
y : 0,
dx : 1,
dy : 0,
ang : 0,
dr : 0,
radius : 30,
holdFrames : 0, // time to wait befor firing ball
draw(){
ctx.strokeStyle = "black";
ctx.lineWidth = 2;
ctx.setTransform(1,0,0,1,this.x,this.y);
ctx.rotate(this.ang);
ctx.beginPath();
ctx.moveTo(0,0);
ctx.arc(0,0,this.radius,0,Math.PI * 2);
ctx.stroke();
ctx.setTransform(1,0,0,1,0,0);
},
update(){
if(this.holdFrames > 0){
this.holdFrames -= 1;
this.ang += this.dr;
}else{
this.dx *= (1-airFriction); // add friction due to air
this.dy *= (1-airFriction);
this.dr *= (1-spinFriction); // add friction to the balls spin
var ballVelocity = Math.sqrt(this.dx * this.dx + this.dy * this.dy);
var nx = this.dx / ballVelocity; // get normalised vector of motion
var ny = this.dy / ballVelocity;
var accel = spinCof * ballVelocity * this.dr; // get the acceleration due to spin
this.dx -= ny * accel; // apply acceleration perpendicular to motion
this.dy += nx * accel; //
this.x += this.dx;
this.y += this.dy;
this.ang += this.dr;
if(this.x > ctx.canvas.width + this.radius){ // ball off canvas so reset
this.dx = Math.random() * 5 + 4; // set random x speed
this.dy = 0;
this.dr = (Math.random() * 0.5) * (Math.random() < 0.5 ? -1 : 1); // set random spin
this.x = 0;
this.y = canvas.height / 2;
this.holdFrames = 60;
}
}
}
}
// Main animation loop
function mainLoop1(time){
ctx.globalCompositeOperation = "destination-out";
ctx.globalAlpha = 0.1;
ctx.fillRect(0,0,w,h); // clear da screen
ctx.globalCompositeOperation = "source-over";
ctx.globalAlpha = 1;
ball.update();
ball.draw();
requestAnimationFrame(mainLoop1);
}
// start the animation
requestAnimationFrame(mainLoop1);
Related
I'm currently working on a raycaster in Java, and so far, I have the floor correctly textured. The problem, however, is that the floor doesn't scroll. In other words, when I move the camera in the projection, the floor stays the same, yet the walls move as expected. I'm really not sure what I'm doing wrong. I took almost all the code from this reference. Note that I took some liberties when pasting the code in that I used some pseudocode.
I tried applying a player offset to the tileX and tileY variables, e.g., tileX += player.x, and all I got was a floor that scrolls far too quickly and incorrectly.
for every ray:
... // other stuff relating to the walls above here.
int start = (int)(wallY + wallHeight + 1);
double directionCos = cos(rad(ray.getAngle()));
double directionSin = sin(rad(ray.getAngle()));
int textureDim = 16;
for (int y = start; y < screenHeight; y++) {
double distance = screenHeight / (2.f * y - screenHeight);
distance /= cos(rad(player.getAngle()) - rad(ray.getAngle()));
// The source I grabbed the code from actually appends the player's x and y to the tileX and tileY variables, but this completely messes up the textures when I try to.
double tileX = distance * directionCos;
double tileY = distance * directionSin;
int textureX = Math.floorMod((int)(tileX * textureDim), textureDim);
int textureY = Math.floorMod((int)(tileY * textureDim), textureDim);
int rgb = floorTexture.getRGB(textureX, textureY);
projectionFloor.setRGB((int)wallX, y, rgb);
}
Below is an image of the floor.
Below is an animation visualizing the problem.
Below is an animation visualizing what happens if I try to apply a player position offset:
Fixed it on my own. Turns out that, yes, you do have to account for the player's position (shocker!); the source I got the code from just didn't do it correctly.
DTPP = distance to projection plane.
for every pixel y from wallY + wallHeight + 1 to projectionHeight:
double r = y - this.getPreferredSize().height / 2.f;
double d = (CAMERA_HEIGHT * DTPP / r) / ANGLE;
double tileX = CAMERA_X + d * RAY_COSANGLE;
double tileY = CAMERA_Y + d * RAY_SINANGLE;
int textureX = Math.floorMod((int) (tileX * TEXTURE_SIZE /
TEXTURE_SCALE), TEXTURE_SIZE);
int textureY = Math.floorMod((int) (tileY * TEXTURE_SIZE /
TEXTURE_SCALE), TEXTURE_SIZE);
... (drawing occurs here)
I'm trying to add some distance (e.g. 10px) between a segment (arc) of the pie chart and it's center without success, here's what i've tried so far:
int value = 20; // example
double arcAngle = (value * 360 / 100);
double angle = 360 - (arcAngle / 2); // direction to add the distance to (center of arc)
double newX = pieCenterX + Math.cos(angle * Math.PI / 180.0) * 10;
double newY = pieCenterY + Math.sin(angle * Math.PI / 180.0) * 10;
// then drawing the arc with new x and y
g.fill(new Arc2D.Double(newX, newY, bounds.getWidth(), bounds.getHeight(), startAngle, arcAngle, Arc2D.PIE));
Ideally i should end up with something like that:
I don't know much on how to approach this, so my code was taken from examples i found elsewhere.
Usually zero angle is OX direction (right). So you have to make correction by 90 degrees (if your coordinate system is counterclockwise)
double angle = 90 + 360 - (arcAngle / 2);
I want to draw an arc using center point,starting point,ending point on opengl surfaceview.I have tried this given below code so far. This function draws the expected arc if we give the value for start_line_angle and end_line_angle manually (like start_line_angle=0 and end_line_angle=90) in degree.
But I need to draw an arc with the given co-ordinates(center point,starting point,ending point) and calculating the start_line_angle and end_line_angle programatically.
This given function draws an arc with the given parameters but not giving the desire result. I've wasted my 2 days for this. Thanks in advance.
private void drawArc(GL10 gl, float radius, float cx, float cy, float start_point_x, float start_point_y, float end_point_x, float end_point_y) {
gl.glLineWidth(1);
int start_line_angle;
double sLine = Math.toDegrees(Math.atan((cy - start_point_y) / (cx - start_point_x))); //normal trigonometry slope = tan^-1(y2-y1)/(x2-x1) for line first
double eLine = Math.toDegrees(Math.atan((cy - end_point_y) / (cx - end_point_x))); //normal trigonometry slope = tan^-1(y2-y1)/(x2-x1) for line second
//cast from double to int after round
int start_line_Slope = (int) (sLine + 0.5);
/**
* mapping the tiriogonometric angle system to glsurfaceview angle system
* since angle system in trigonometric system starts in anti clockwise
* but in opengl glsurfaceview angle system starts in clock wise and the starting angle is 90 degree of general trigonometric angle system
**/
if (start_line_Slope <= 90) {
start_line_angle = 90 - start_line_Slope;
} else {
start_line_angle = 360 - start_line_Slope + 90;
}
// int start_line_angle = 270;
// int end_line_angle = 36;
//casting from double to int
int end_line_angle = (int) (eLine + 0.5);
if (start_line_angle > end_line_angle) {
start_line_angle = start_line_angle - 360;
}
int nCount = 0;
float[] stVertexArray = new float[2 * (end_line_angle - start_line_angle)];
float[] newStVertextArray;
FloatBuffer sampleBuffer;
// stVertexArray[0] = cx;
// stVertexArray[1] = cy;
for (int nR = start_line_angle; nR < end_line_angle; nR++) {
float fX = (float) (cx + radius * Math.sin((float) nR * (1 * (Math.PI / 180))));
float fY = (float) (cy + radius * Math.cos((float) nR * (1 * (Math.PI / 180))));
stVertexArray[nCount * 2] = fX;
stVertexArray[nCount * 2 + 1] = fY;
nCount++;
}
//taking making the stVertextArray's data in reverse order
reverseArray = new float[stVertexArray.length];//-2 so that no repeatation occurs of first value and end value
int count = 0;
for (int i = (stVertexArray.length) / 2; i > 0; i--) {
reverseArray[count] = stVertexArray[(i - 1) * 2 + 0];
count++;
reverseArray[count] = stVertexArray[(i - 1) * 2 + 1];
count++;
}
//reseting the counter to initial value
count = 0;
int finalArraySize = stVertexArray.length + reverseArray.length;
newStVertextArray = new float[finalArraySize];
/**Now adding all the values to the single newStVertextArray to draw an arc**/
//adding stVertextArray to newStVertextArray
for (float d : stVertexArray) {
newStVertextArray[count++] = d;
}
//adding reverseArray to newStVertextArray
for (float d : reverseArray) {
newStVertextArray[count++] = d;
}
Log.d("stArray", stVertexArray.length + "");
Log.d("reverseArray", reverseArray.length + "");
Log.d("newStArray", newStVertextArray.length + "");
ByteBuffer bBuff = ByteBuffer.allocateDirect(newStVertextArray.length * 4);
bBuff.order(ByteOrder.nativeOrder());
sampleBuffer = bBuff.asFloatBuffer();
sampleBuffer.put(newStVertextArray);
sampleBuffer.position(0);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(2, GL10.GL_FLOAT, 0, sampleBuffer);
gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, nCount * 2);
gl.glLineWidth(1);
}
To begin with the trigonometry you may not simply use the atan to find degrees of the angle. You need to check what quadrant the vector is in and increase or decrease the result you get from atan. Better yet use atan2 which should include both dx and dy and do the job for you.
You seem to create the buffer so that a point is created per degree. This is not the best solution as for large radius that might be too small and for small radius this is way too much. Tessellation should include the radius as well such that number of points N is N = abs((int)(deltaAngle*radius*tessellationFactor)) then use angleFragment = deltaAngle/N but make sure that N is greater then 0 (N = N?N:1). The buffer size is then 2*(N+1) of floats and the iteration if for(int i=0; i<=N; i++) angle = startAngle + angleFragment*i;.
As already pointed out you need to define the radius of the arc. It is quite normal to use an outside source the way you do and simply force it to that value but use the 3 points for center and the two borders. Some other options that usually make sense are:
getting the radius from the start line
getting the radius from the shorter of the two lines
getting the average of the two
interpolate the two to get an elliptic curve (explained below)
To interpolate the radius you need to get the two radiuses startRadius and endRadius. Then you need to find the overall radius which was already used as deltaAngle above (watch out when computing this one, it is more complicated as it seems, for instance drawing from 320 degrees to 10 degrees results in deltaAngle = 50). Anyway the radius for a specific point is then simply radius = startRadius + (endRadius-startRadius)*abs((angleFragment*i)/deltaAngle). This represents a simple linear interpolation in polar coordinate system which is usually used to interpolate vector in matrices and is the core functionality to get nice animations.
There are some other ways of getting the arc points which may be better performance wise but I would not suggest them unless and until you need to optimize your code which should be very late in production. You may simply keep stepping toward the next point and correcting the radius (this is only a concept):
vec2 start, end, center; // input values
float radius; // input value
// making the start and end relative to center
start -= center;
end -= center;
vec2 current = start/length(start) * radius; // current position starts in first vector
vec2 target = end/length(end) * radius; // should be the last point
outputBuffer[0] = current+center; // insert the first point
for(int i=1;; i++) { // "break" will need to exit the loop, we need index only for the buffer
vec2 step = vec2(current.y, -(current.x)); // a tangential vector from current start point according to center
step = step/length(step) / tessellationScale; // normalize and apply tessellation
vec2 next = current + step; // move tangentially
next = next/length(next) * radius; // normalize and set the
if(dot(current-target, next-target) > .0) { // when we passed the target vector
current = next; // set the current point
outputBuffer[i] = current+center; // insert into buffer
}
else {
current = target; // simply use the target now
outputBuffer[i] = current+center; // insert into buffer
break; // exit
}
}
Since in the digital world a real collision almost never happens, we will always have a situation where the "colliding" circle overlaps the rectangle.
How to put back the circle in the situation where it collides perfectly with the rectangle without overlap?
Suppose that the rectangle is stopped (null velocity) and axis-aligned.
I would solve this problem with a posteriori approach (in two dimensions).
In short I have to solve this equation for t:
Where:
is a number that answers to the question: how many frames ago did the
collision happen perfectly?
is the radius of the circle.
is the center of the circle
is its velocity.
and are functions that return the x and y coordinates of
the point where the circle and the rectangle collide (when the circle is
at position, that is in the position in which perfectly collide with the rectangle).
Recently I solved a similar problem for collisions between circles, but now I don't know the law of the functions A and B.
After years of staring at this problem, and never coming up with a perfect solution, I've finally done it!
It's pretty much a straight forward algorithm, no need for looping and approximations.
This is how it works at a higher level:
Calculate intersection times with each side's plane IF the path from current point to future point crosses that plane.
Check each side's quadrant for single-side intersection, return the intersection.
Determine the corner that the circle is colliding with.
Solve the triangle between the current point, the corner, and the intersecting center (radius away from the corner).
Calculate time, normal, and intersection center.
And now to the gory details!
The input to the function is bounds (which has a left, top, right, bottom) and a current point (start) and a future point (end).
The output is a class called Intersection which has x, y, time, nx, and ny.
{x, y} is the center of the circle at intersection time.
time is a value from 0 to 1 where 0 is at start and 1 is at end
{nx, ny} is the normal, used for reflecting the velocity to determine the new velocity of the circle
We start off with caching variables we use often:
float L = bounds.left;
float T = bounds.top;
float R = bounds.right;
float B = bounds.bottom;
float dx = end.x - start.x;
float dy = end.y - start.y;
And calculating intersection times with each side's plane (if the vector between start and end pass over that plane):
float ltime = Float.MAX_VALUE;
float rtime = Float.MAX_VALUE;
float ttime = Float.MAX_VALUE;
float btime = Float.MAX_VALUE;
if (start.x - radius < L && end.x + radius > L) {
ltime = ((L - radius) - start.x) / dx;
}
if (start.x + radius > R && end.x - radius < R) {
rtime = (start.x - (R + radius)) / -dx;
}
if (start.y - radius < T && end.y + radius > T) {
ttime = ((T - radius) - start.y) / dy;
}
if (start.y + radius > B && end.y - radius < B) {
btime = (start.y - (B + radius)) / -dy;
}
Now we try to see if it's strictly a side intersection (and not corner). If the point of collision lies on the side then return the intersection:
if (ltime >= 0.0f && ltime <= 1.0f) {
float ly = dy * ltime + start.y;
if (ly >= T && ly <= B) {
return new Intersection( dx * ltime + start.x, ly, ltime, -1, 0 );
}
}
else if (rtime >= 0.0f && rtime <= 1.0f) {
float ry = dy * rtime + start.y;
if (ry >= T && ry <= B) {
return new Intersection( dx * rtime + start.x, ry, rtime, 1, 0 );
}
}
if (ttime >= 0.0f && ttime <= 1.0f) {
float tx = dx * ttime + start.x;
if (tx >= L && tx <= R) {
return new Intersection( tx, dy * ttime + start.y, ttime, 0, -1 );
}
}
else if (btime >= 0.0f && btime <= 1.0f) {
float bx = dx * btime + start.x;
if (bx >= L && bx <= R) {
return new Intersection( bx, dy * btime + start.y, btime, 0, 1 );
}
}
We've gotten this far so we know either there's no intersection, or it's collided with a corner. We need to determine the corner:
float cornerX = Float.MAX_VALUE;
float cornerY = Float.MAX_VALUE;
if (ltime != Float.MAX_VALUE) {
cornerX = L;
} else if (rtime != Float.MAX_VALUE) {
cornerX = R;
}
if (ttime != Float.MAX_VALUE) {
cornerY = T;
} else if (btime != Float.MAX_VALUE) {
cornerY = B;
}
// Account for the times where we don't pass over a side but we do hit it's corner
if (cornerX != Float.MAX_VALUE && cornerY == Float.MAX_VALUE) {
cornerY = (dy > 0.0f ? B : T);
}
if (cornerY != Float.MAX_VALUE && cornerX == Float.MAX_VALUE) {
cornerX = (dx > 0.0f ? R : L);
}
Now we have enough information to solve for the triangle. This uses the distance formula, finding the angle between two vectors, and the law of sines (twice):
double inverseRadius = 1.0 / radius;
double lineLength = Math.sqrt( dx * dx + dy * dy );
double cornerdx = cornerX - start.x;
double cornerdy = cornerY - start.y;
double cornerdist = Math.sqrt( cornerdx * cornerdx + cornerdy * cornerdy );
double innerAngle = Math.acos( (cornerdx * dx + cornerdy * dy) / (lineLength * cornerdist) );
double innerAngleSin = Math.sin( innerAngle );
double angle1Sin = innerAngleSin * cornerdist * inverseRadius;
// The angle is too large, there cannot be an intersection
if (Math.abs( angle1Sin ) > 1.0f) {
return null;
}
double angle1 = Math.PI - Math.asin( angle1Sin );
double angle2 = Math.PI - innerAngle - angle1;
double intersectionDistance = radius * Math.sin( angle2 ) / innerAngleSin;
Now that we solved for all sides and angles, we can determine time and everything else:
// Solve for time
float time = (float)(intersectionDistance / lineLength);
// If time is outside the boundaries, return null. This algorithm can
// return a negative time which indicates the previous intersection.
if (time > 1.0f || time < 0.0f) {
return null;
}
// Solve the intersection and normal
float ix = time * dx + start.x;
float iy = time * dy + start.y;
float nx = (float)((ix - cornerX) * inverseRadius);
float ny = (float)((iy - cornerY) * inverseRadius);
return new Intersection( ix, iy, time, nx, ny );
Woo! That was fun... this has plenty of room for improvements as far as efficiency goes. You could reorder the side intersection checking to escape as early as possible while making as few calculations as possible.
I was hoping there would be a way to do it without trigonometric functions, but I had to give in!
Here's an example of me calling it and using it to calculate the new position of the circle using the normal to reflect and the intersection time to calculate the magnitude of reflection:
Intersection inter = handleIntersection( bounds, start, end, radius );
if (inter != null)
{
// Project Future Position
float remainingTime = 1.0f - inter.time;
float dx = end.x - start.x;
float dy = end.y - start.y;
float dot = dx * inter.nx + dy * inter.ny;
float ndx = dx - 2 * dot * inter.nx;
float ndy = dy - 2 * dot * inter.ny;
float newx = inter.x + ndx * remainingTime;
float newy = inter.y + ndy * remainingTime;
// new circle position = {newx, newy}
}
And I've posted the full code on pastebin with a completely interactive example where you can plot the starting and ending points and it shows you the time and resulting bounce off of the rectangle.
If you want to get it running right away you'll have to download code from my blog, otherwise stick it in your own Java2D application.
EDIT:
I've modified the code in pastebin to also include the collision point, and also made some speed improvements.
EDIT:
You can modify this for a rotating rectangle by using that rectangle's angle to un-rotate the rectangle with the circle start and end points. You'll perform the intersection check and then rotate the resulting points and normals.
EDIT:
I modified the code on pastebin to exit early if the bounding volume of the path of the circle does not intersect with the rectangle.
Finding the moment of contact isn't too hard:
You need the position of the circle and rectangle at the timestep before the collision (B) and the timestep after (A). Calculate the distance from the center of the circle to the line of the rectangle it collides with at times A and B (ie, a common formula for a distance from a point to a line), and then the time of collision is:
tC = dt*(dB-R)/(dA+dB),
where tC is the time of collision, dt is the timestep, dB is the distance to line before the collision, dA is the distance after the collision, and R is the radius of the circle.
This assumes everything is locally linear, that is, that your timesteps are reasonably small, and so that the velocity, etc, don't change much in the timestep where you calculate the collision. This is, after all, the point of timesteps: in that with a small enough timestep, non-linear problems are locally linear. In the equation above I take advantage of that: dB-R is the distance from the circle to the line, and dA+dB is the total distance moved, so this question just equates the distance ratio to the time ratio assuming everything is approximately linear within the timestep. (Of course, at the moment of collision the linear approximation isn't its best, but to find the moment of collision, the question is whether it's linear within a timestep up to to moment of collision.)
It's a non-linear problem, right?
You take a time step and move the ball by its displacement calculated using velocity at the start of the step. If you find overlap, reduce the step size and recalculate til convergence.
Are you assuming that the balls and rectangles are both rigid, no deformation? Frictionless contact? How will you handle the motion of the ball after contact is made? Are you transforming to a coordinate system of the contact (normal + tangential), calculating, then transforming back?
It's not a trivial problem.
Maybe you should look into a physics engine, like Box2D, rather than coding it yourself.
I am trying to make some sort of 3D Editor with Java and OpenGL. And now I'm implementing the basic functions of an 3D Editor like rotating the camera around a specific Position and zooming. Next I want to do a 3D Picking to select Objects,Lines and Vertices in 3D-Space with the Mouse. I thought this is gonna to be easy because I can already select Objects when the Camera is focusing them.
Here is the example of the Selection of Objects with the Camera focus:
In the Class Camera there is this Method:
public boolean isVecInFocus(Vec3 vec) {
//returns the distance between camera and target
float c = new Vec3(posX,posY,posZ).getDistanceTo(vec);
// returns a Vector by drawing an imiginary line with the length of c and the position and rotation of the camera
Vec3 target = getFocusedPoint(c);
//checks if the calculated Vector is near to the target
if(target.x > vec.x - 0.05f && target.x < vec.x + 0.05f && target.y > vec.y - 0.05f && target.y < vec.y + 0.05f && target.z > vec.z - 0.05f && target.z < vec.z + 0.05f) {
return true;
} else {
return false;
}
}
Now, I want to do the same with the Mouse input:
//Mouse positions
float mX = Mouse.getX();
float mY = Mouse.getY();
//My test Vector
Vec3 vec = new Vec3(-5,5,-8);
//Camera Position
Vec3 camV = new Vec3(cam.getPosX(),cam.getPosY(),cam.getPosZ());
//Distance from Test Vector to Camera
float c = camV.getDistanceTo(vec);
//Calculating of the aspect between width and height (Because fov_x and fov_y are different because of the Screen Resolution, I think)
float aspect = (float) sb.getDisplayWidth() / (float) sb.getDisplayHeight();
//Normal fov refers to fov_y, so here is the fov_x
float fovx = cam.fov * aspect;
//Changing the Rotations to calculate the target Vector with the values of the Mouse position and rotations , not the Camera
float rotY = cam.getRotationY() + (fovx / (float) sb.getDisplayWidth()) * (mX) - (fovx / 2F);
float rotX = cam.getRotationX() + (cam.fov / (float) sb.getDisplayHeight()) * ((float) sb.getDisplayHeight() - mY) - (cam.fov / 2F);
//Calculating the target Vector with simple Math ...
double xDis = c * Math.sin(Math.toRadians(rotY)) * Math.cos(Math.toRadians(rotX));
double yDis = c * Math.sin(Math.toRadians(rotX));
double zDis = c * Math.cos(Math.toRadians(rotY)) * Math.cos(Math.toRadians(rotX));
float posX = (float) (camV.x + xDis);
float posY = (float) (camV.y - yDis);
float posZ = (float) (camV.z - zDis);
Vec3 target = new Vec3(posX,posY,posZ);
//Check if the target Vector and the Test Vector are the same.
If I use this Code, and point with my Mouse at the Test-Vector, the result is not right. The accuracy of the Point gets lower, the bigger the difference between Screen-middle and Mouse position is.
I think it has something to do with the OpenGL Perspective, but I'm not sure ...