I am currently developing a tower defense game in java from scratch and I am reworking the bullet collisions. for this I need to calculate the distance between a given point and a line segment. I have already written a function to do just that, but it does often give the distance from one of the points when it is not supposed to.
the line segment class:
public class LineSegment {
public Vector2DK p;
public Vector2DK q;
/**
* Creates a line segment between the points P and Q
* #param p Point P
* #param q Point Q
*/
public LineSegment(Vector2DK p, Vector2DK q) {
this.p = p;
this.q = q;
}
/**
* Calculates the distance to point R
* #param r Point R
* #return Distance
*/
public double distanceFrom(Vector2DK r) {
// after trying what feels like everything I might have gotten a little confused(stupid errors ahead)
Vector2DP differenceVector = r.subtract(p).toPolar();
Vector2DP differenceVector2 = r.subtract(q).toPolar();
double alpha = differenceVector.getAngle() - q.subtract(p).getAngle();
double beta = differenceVector2.getAngle() - q.subtract(p).getAngle();
if (alpha < Math.PI / 2 && alpha > -Math.PI / 2) {
return p.distanceTo(r);
} else if (beta > Math.PI / 2 || beta < -Math.PI / 2) {
return q.distanceTo(r);
}
return Math.abs(differenceVector.getMagnitude() * Math.sin(alpha));
}
public static void main(String[] args) {
// a main method for testing
// I already added a case where the bullet of the tower flew right thru the enemy(but I probably got the wrong tick, so the values are probably not good for testing)
Vector2DK linePoint0 = new Vector2DK(339.9354152826523, 374.7835775987438);
Vector2DK linePoint1 = new Vector2DK(317.79869321314067, 388.4287303893724);
Vector2DK point = new Vector2DK(290.0194200000002, 400.0);
LineSegment lineSegment = new LineSegment(linePoint0, linePoint1);
Line line = new Line(linePoint0, linePoint1);
System.out.println(lineSegment.distanceFrom(point));
}
}
my two vector classes:
public class Vector2DK implements Vector2D {
private double x;
private double y;
public Vector2DK(double x, double y) {
this.x = x;
this.y = y;
}
public Vector2DK(Vector2D vector) {
Vector2DK vector2DK = vector.toKartesian();
x = vector2DK.x;
y = vector2DK.y;
}
public void copyToSelf(Vector2DK vector) {
x = vector.x;
y = vector.y;
}
#Override
public String toString() {
return String.format("Vector2DK(%s, %s)", x, y);
}
#Override
public Vector2DK toKartesian() {
return new Vector2DK(x, y);
}
#Override
public Vector2DP toPolar() {
return new Vector2DP(getMagnitude(), getAngle());
}
#Override
public double getAngle() {
return Math.atan2(y, x);
}
#Override
public double getMagnitude() {
return Math.sqrt(getMagnitudeSquare());
}
#Override
public double getX() {
return x;
}
#Override
public double getY() {
return y;
}
#Override
public void setAngle(double angle) {
Vector2DP vector = toPolar();
vector.setAngle(angle);
copyToSelf(vector.toKartesian());
}
#Override
public void setMagnitude(double magnitude) {
Vector2DP vector = toPolar();
vector.setAngle(magnitude);
copyToSelf(vector.toKartesian());
}
#Override
public void setX(double x) {
this.x = x;
}
#Override
public void setY(double y) {
this.y = y;
}
#Override
public double getMagnitudeSquare() {
return x * x + y * y;
}
#Override
public double distanceTo(Vector2D vector) {
return Math.sqrt(MathFunc.square(x - vector.getX()) + MathFunc.square(y - vector.getY()));
}
#Override
public void normalize() {
double magnitude = getMagnitude();
x /= magnitude;
y /= magnitude;
}
#Override
public void reverse() {
x = -x;
y = -y;
}
#Override
public Vector2D add(Vector2D vector) {
return new Vector2DK(x + vector.getX(), y + vector.getY());
}
#Override
public Vector2D subtract(Vector2D vector) {
return new Vector2DK(x - vector.getX(), y - vector.getY());
}
#Override
public Vector2D scale(double value) {
return new Vector2DK(x * value, y * value);
}
#Override
public void addWith(Vector2D vector) {
x += vector.getX();
y += vector.getY();
}
#Override
public void subtractWith(Vector2D vector) {
x -= vector.getX();
y -= vector.getY();
}
#Override
public void scaleWith(double value) {
x *= value;
y *= value;
}
#Override
public double dotProduct(Vector2D vector) {
return x * vector.getX() + y * vector.getY();
}
}
and:
public class Vector2DP implements Vector2D {
private double magnitude;
private double angle;
public Vector2DP(double magnitude, double angle) {
this.magnitude = magnitude;
this.angle = angle;
}
public Vector2DP(Vector2DP vector) {
Vector2DP vector2DP = vector.toPolar();
this.magnitude = vector.magnitude;
this.angle = vector.angle;
}
public void copyToSelf(Vector2DP vector) {
magnitude = vector.magnitude;
angle = vector.angle;
}
#Override
public String toString() {
return String.format("Vector2DP(%su, %s°)", magnitude, Math.toDegrees(angle));
}
#Override
public Vector2DK toKartesian() {
return new Vector2DK(getX(), getY());
}
#Override
public Vector2DP toPolar() {
return new Vector2DP(magnitude, angle);
}
#Override
public double getAngle() {
return angle;
}
#Override
public double getMagnitude() {
return magnitude;
}
#Override
public double getX() {
return Math.cos(angle) * magnitude;
}
#Override
public double getY() {
return Math.sin(angle) * magnitude;
}
#Override
public void setAngle(double angle) {
this.angle = angle;
}
#Override
public void setMagnitude(double magnitude) {
this.magnitude = magnitude;
}
#Override
public void setX(double x) {
Vector2DK vector = toKartesian();
vector.setX(x);
copyToSelf(vector.toPolar());
}
#Override
public void setY(double y) {
Vector2DK vector = toKartesian();
vector.setY(y);
copyToSelf(vector.toPolar());
}
#Override
public double getMagnitudeSquare() {
return magnitude * magnitude;
}
#Override
public double distanceTo(Vector2D vector) {
return subtract(vector).getAngle();
}
#Override
public void normalize() {
magnitude = 1;
}
#Override
public void reverse() {
angle += angle < Math.PI ? Math.PI : -Math.PI;
}
#Override
public Vector2D add(Vector2D vector) {
return toKartesian().add(vector).toPolar();
}
#Override
public Vector2D subtract(Vector2D vector) {
return toKartesian().add(vector).toPolar();
}
#Override
public Vector2D scale(double value) {
return new Vector2DP(magnitude * value, angle);
}
#Override
public void addWith(Vector2D vector) {
copyToSelf((Vector2DP) add(vector));
}
#Override
public void subtractWith(Vector2D vector) {
copyToSelf((Vector2DP) subtract(vector));
}
#Override
public void scaleWith(double value) {
magnitude *= value;
}
#Override
public double dotProduct(Vector2D vector) {
Vector2DP vector2DP = vector.toPolar();
return magnitude * vector2DP.magnitude * Math.cos(angle - vector2DP.angle);
}
}
Consider the next Python code (hope it is easy to translate it).
At first function check dot products of segment vector and vectors from the start and end of segment to the point.
If projection of point onto the line lies outside the segment, sign of dot product reveals this fact, and we return distance to the closest segment end (points A,B,C,D at the picture)
Otherwise we return length of projection (formula from wiki) (point E at the picture)
hypot gives vector length (like your getMagnitude)
import math
def pt_seg_dist(px, py, qx, qy, rx, ry):
qpx = qx - px
qpy = qy - py
rpx = rx - px
rpy = ry - py
if rpx * qpx + rpy * qpy <= 0:
return math.hypot(rpx, rpy)
rqx = rx - qx
rqy = ry - qy
if rqx * qpx + rqy * qpy >= 0:
return math.hypot(rqx, rqy)
return abs(rpx * qpy - rpy * qpx) / math.hypot(qpx, qpy)
print(pt_seg_dist(0, 0, 1, 0, 0.5, 2))
print(pt_seg_dist(0, 0, 1, 0, -2, 2))
print(pt_seg_dist(0, 0, 1, 0, 3, -2))
>>>
2.0
2.8284271247461903
2.8284271247461903
Related
Ok so i have rectangle that should be created based on: method point that will crete coordinates of it center and values of hight and width, all value are based on this test
public void testRectangle1() {
Point center = new Point(20, 30);
Rectangle rect = new Rectangle(center, 20, 20);
assertAll(
() -> assertEquals(10, rect.getTopLeft().getX()),
() -> assertEquals(20, rect.getTopLeft().getY()),
() -> assertEquals(30, rect.getBottomRight().getX()),
() -> assertEquals(40, rect.getBottomRight().getY()),
() -> assertEquals(20, rect.getWidth()),
() -> assertEquals(20, rect.getHeight())
);
}
I have prewritten class point that i will add here for overall clarity
package net.thumbtack.school.figures.v1;
public class Point {
private int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public Point() {
this(0, 0);
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public void moveTo(int newX, int newY) {
x = newX;
y = newY;
}
public void moveRel(int dx, int dy) {
x += dx;
y += dy;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Point other = (Point) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}
And this is class for creating rectangle
package net.thumbtack.school.figures.v1;
public class Rectangle {
public int width;
public int height;
public Point center;
public int xCenter;
public int yCenter;
private Point point;
public Rectangle(Point center, int width, int height) {
this.width=width;
this.height=height;
this.center=center;
}
public Point getTopLeft() {
Point point = getCenter();
point.moveRel(- width / 2, - height / 2);
return point;
}
public Point getBottomRight() {
Point point = getCenter();
point.moveRel(width / 2, height / 2);
return point;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public Point getCenter() {
Point center = new Point(xCenter, yCenter);
return center;
}
So problem is in constructor public Rectangle(Point center, int width, int height) when i run the test it returns wirng values
expected: <10> but was: <-10>
Comparison Failure:
Expected :10
Actual :-10
expected: <20> but was: <-10>
Comparison Failure:
Expected :20
Actual :-10
expected: <30> but was: <10>
Comparison Failure:
Expected :30
Actual :10
expected: <40> but was: <10>
Comparison Failure:
Expected :40
Actual :10
I dont this that the problem is into other methods becouse when i use them in different but simmilar constrictors everything works.
As maloomeister mentioned you must init xCenter or yCenter before used,or the value of xCenter and yCenter is 0.
modify getCenter() method:
public Point getCenter() {
Point point = new Point(center.getX(), center.getY());
return point;
}
i wan't to create effect similar to that of photoshop when you press ctrl+T that produces frame around the object and resize but i want to just change the position of the contained object not scaling them what i created so far does the job but the movement is exagerrated and i can't figure out what is wrong with my codehere i am just trying with the northwest handler
thanks in advance
here is images illustrating exactly what i want
the first image is original group with blue circles are controllers
the second is the group after resizing the group by dragging the north west
but the components gets scaled also
the third one is exactly what i want to achieve only change positions without changing the scale
//this creates the bounding box
public static void cr_resizer(Group root,double x,double y,double X,double Y) {
Rectangle major=new Rectangle(x-10,y-10,X-x+20,Y-y+20);
major.setFill(Color.TRANSPARENT);
major.setId("major");
major.setStrokeWidth(3);
major.setStroke(Color.BLUE);
major.setDisable(true);
Circle NW=new Circle(x-10,y-10,3);
Circle N=new Circle(((x+X)/2),y-10,3);
Circle NE=new Circle(X+10,y-10,3);
Circle W=new Circle(x-10,(Y+y)/2,3);
Circle E=new Circle(X+10,(Y+y)/2,3);
Circle SE=new Circle(X+10,Y+10,3);
Circle S=new Circle(((x+X)/2),Y+10,3);
Circle SW=new Circle(x-10,Y+10,3);
resize_move( root,NW,SE);
root.getChildren().addAll(major,NW,N,NE,SE,S,SW,E,W);
}
//this function calculates the calculate the distance of the mover point from the opposing point
// to caclulate the scaling factor theen apply it to componnents of the group
public static void resize_move(Group root,Circle mover,Circle op) {
double[]start={mover.getCenterX(),mover.getCenterY()};
double[]end={op.getCenterX(),op.getCenterY()};
double[]strt_length=dis2_vec_d(start, end);
mover.setOnMouseClicked(ev->{
difx=ev.getX();
dify=ev.getY();
});
mover.setOnMouseDragged(ev->{
double diffx=ev.getX()-difx;
double diffy=ev.getY()-dify;
System.out.println(diffx);
System.out.println(diffy);
difx=ev.getX();
dify=ev.getY();
mover.setCenterX(ev.getX());
mover.setCenterY(ev.getY());
double[] newp= {mover.getCenterX(),mover.getCenterY()};
double[]end_length=dis2_vec_d(newp, end);
double[]factor = {end_length[0]/strt_length[0],end_length[1]/strt_length[1]};
for (Node nod:root.getChildren()) {
if (nod instanceof Circle) {
if (nod != mover) {
move_circ((Circle) nod,op,factor);
}
}
}
});
}
//this function relocate the position of the circle according to the position of the custom axis point
public static void move_circ(Circle cir,Circle op,double[]factor) {
double[] axis= {op.getCenterX(),op.getCenterY()};
double[] strt_point= {cir.getCenterX(),cir.getCenterY()};
double[] nstrt_point= new_cord(axis,strt_point,factor);
cir.setCenterX(nstrt_point[0]);
cir.setCenterY(nstrt_point[1]);
}
//this function scale the position of the point in relation to another point
public static double[] new_cord(double[]axis,double[]point,double[]factor) {
double[]strt_length=dis2_vec_d(point,axis);
double[]new_length= {strt_length[0]*factor[0],strt_length[1]*factor[1]};
double[]new_point= {new_length[0]+axis[0],new_length[1]+axis[1]};
return new_point;
}
//this function calculates the distance
public static double[] dis2_vec_d(double[]p1,double[]p2) {
double[] vec = new double[2];
vec[0]=p1[0]-p2[0];
vec[1]=p1[1]-p2[1];
return vec;
}
It looks like you just want to make your Node draggable. I created a class that does this, pasted below.
You might have to replace a few instances of a class called GameScreen in my code below.
public class Draggable {
////////////////////////////////////////////////////////////////////////////
//variables
AtomicBoolean myPressed = new AtomicBoolean(false);
Point2D myInitialTranslates;
Point2D dragInitialTranslates;
EventHandler<? super MouseEvent> onMouseReleased;
EventHandler<? super MouseEvent> onMousePressed;
EventHandler<? super MouseEvent> onMouseDragged;
OnDrag onDrag;
boolean stayWithinBounds = true;
double minX = 0;
double maxX = WIDTH;
double minY = 0;
double maxY = GameScreen.PLAY_AREA_HEIGHT;
boolean doNotTranslate = false;
//handleX and handleY are offsets used strictly for the callbacks, they are not used for the translation of the destination Node.
double handleX = 0;
double handleY = 0;
double X;
double Y;
boolean reverseX = false;
boolean reverseY = false;
float amountOfTargetNodeToAllowOutsideLimit = 0f;
public void setOnDrag(OnDrag onDrag) {
this.onDrag = onDrag;
}
////////////////////////////////////////////////////////////////////////////
//constructors
public Draggable() {
}
public Draggable(double handleX, double handleY) {
this.handleX = handleX;
this.handleY = handleY;
}
////////////////////////////////////////////////////////////////////////////
//methods
public void makeDraggable(Node source, Node target, double dragAdjustmentRatioX, double dragAdjustmentRatioY) {
source.setOnMouseDragged((MouseEvent event) -> {
if (myPressed.get() && !doNotTranslate) {
double x = myInitialTranslates.getX() - dragInitialTranslates.getX() + dragAdjustmentRatioX * GameScreen.instance.scaleXToScreen(event.getSceneX());
double y = myInitialTranslates.getY() - dragInitialTranslates.getY() + dragAdjustmentRatioY * GameScreen.instance.scaleYToScreen(event.getSceneY());
double localMaxX = maxX - target.getBoundsInLocal().getWidth() * amountOfTargetNodeToAllowOutsideLimit;
double localMinX = minX - target.getBoundsInLocal().getWidth() * amountOfTargetNodeToAllowOutsideLimit;
if (x > localMinX && x < localMaxX) {
target.setTranslateX(x);
} else {
// Log.debug("X is not within range. x = " + x);
}
double localMaxY = maxY - target.getBoundsInLocal().getHeight() * amountOfTargetNodeToAllowOutsideLimit;
double localMinY = minY - target.getBoundsInLocal().getWidth() * amountOfTargetNodeToAllowOutsideLimit;
if (y > localMinY && y < localMaxY) {
target.setTranslateY(y);
} else {
// Log.debug("Y is not within range. x = " + y);
}
} else {
}
if (onMouseDragged != null) {
onMouseDragged.handle(event);
}
if (onDrag != null) {
if (reverseX) {
X = handleX + dragInitialTranslates.getX() - dragAdjustmentRatioX * GameScreen.instance.scaleXToScreen(event.getSceneX());
} else {
X = handleX - dragInitialTranslates.getX() + dragAdjustmentRatioX * GameScreen.instance.scaleXToScreen(event.getSceneX());
}
if (reverseY) {
Y = handleY + dragInitialTranslates.getY() - dragAdjustmentRatioY * GameScreen.instance.scaleYToScreen(event.getSceneY());
} else {
Y = handleY - dragInitialTranslates.getY() + dragAdjustmentRatioY * GameScreen.instance.scaleYToScreen(event.getSceneY());
}
onDrag.handle(X, Y);
}
});
source.setOnMousePressed((MouseEvent event) -> {
myInitialTranslates = new Point2D(target.getTranslateX(), target.getTranslateY());
dragInitialTranslates = new Point2D(
dragAdjustmentRatioX * GameScreen.instance.scaleXToScreen(event.getSceneX()),
dragAdjustmentRatioY * GameScreen.instance.scaleYToScreen(event.getSceneY()));
myPressed.set(true);
if (onMousePressed != null) {
onMousePressed.handle(event);
}
GameScreen.setCursorMove();
});
source.setOnMouseReleased((MouseEvent event) -> {
myPressed.set(false);
handleX = X;
handleY = Y;
if (onMouseReleased != null) {
onMouseReleased.handle(event);
}
GameScreen.setCursorCustom();
});
}
public void makeDraggable(Node node, double dragAdjustmentRatioX, double dragAdjustmentRatioY) {
makeDraggable(node, node, dragAdjustmentRatioX, dragAdjustmentRatioY);
}
public void setOnMouseReleased(EventHandler<? super MouseEvent> onMouseReleased) {
this.onMouseReleased = onMouseReleased;
}
public void setOnMousePressed(EventHandler<? super MouseEvent> onMousePressed) {
this.onMousePressed = onMousePressed;
}
public void setOnMouseDragged(EventHandler<? super MouseEvent> onMouseDragged) {
this.onMouseDragged = onMouseDragged;
}
public void setAmountOfTargetNodeToAllowOutsideLimit(float amountOfTargetNodeToAllowOutsideLimit) {
this.amountOfTargetNodeToAllowOutsideLimit = amountOfTargetNodeToAllowOutsideLimit;
}
public interface OnDrag {
public void handle(double x, double y);
}
public boolean isStayWithinBounds() {
return stayWithinBounds;
}
public void setStayWithinBounds(boolean stayWithinBounds) {
this.stayWithinBounds = stayWithinBounds;
}
public void setMinMax(double minX, double maxX, double minY, double maxY) {
this.maxX = maxX;
this.minX = minX;
this.minY = minY;
this.maxY = maxY;
}
public void setDoNotTranslate(boolean doNotTranslate) {
this.doNotTranslate = doNotTranslate;
}
public boolean isReverseX() {
return reverseX;
}
public void setReverseX(boolean reverseX) {
this.reverseX = reverseX;
}
public boolean isReverseY() {
return reverseY;
}
public void setReverseY(boolean reverseY) {
this.reverseY = reverseY;
}
public double getHandleX() {
return handleX;
}
public void setHandleX(double handleX) {
this.handleX = handleX;
}
public double getHandleY() {
return handleY;
}
public void setHandleY(double handleY) {
this.handleY = handleY;
}
}
GameScreen.instance.scaleXToScreen and GameScreen.instance.scaleYToScreen just set this to 1. In the future if you scale your window, you might need to adjust for it.
GameScreen.WIDTH and GameScreen.PLAY_HEIGHT set tot he width and height of your scene.
The two method calls to change the mouse cursor can be deleted.
The way you use it is like this...
new Draggable().makeDraggable(nodeYouWantToDrag, 1, 1);
and thats that.
EDIT: it also has callbacks for basic events like onDrag, onMousePressed, onMouseDragged, and onMouseReleased.
How can I utilize my lerp function inside the vector3f class? Currently the lerp function reads like so:
public Vector3f lerp(Vector3f other, float alpha) {
return this.scale(1f - alpha).add(other.scale(alpha));
}
I have position and velocity vectors which use the add function as it updates. Now I want some smooth movement, but, I'm unsure how you would correctly use lerp. I've watched and read a few tutorials but none of them seem to address this kind of functionality. Any help would be much appreciated.
UPDATE:
So I've been watching this video here he has a series of videos on lerp with a very good diagram demonstration, which gave me a clue as to how linear interpolation works, so I decided to give it another shot. I wrote a new Vector2f method like so.
public Vector2f lerpT(Vector2f currentPos, Vector2f newPos, float alpha)
{
return currentPos.scale(1f - alpha).add(newPos.scale(alpha));
//return Vector3f point1 + alpha * (point2 - point1);
}
And my main class is like so:
public class Main {
public static void main(String[] args) throws IOException {
init();
}
public static void init() {
Vector2f currentPosition = new Vector2f(0.3f,0.7f);
Vector2f newPosition = new Vector2f(1.3f,0.8f);
Vector2f lerpPos = new Vector2f().lerpT(currentPosition, newPosition, 0f);
System.out.println("Testing LERP: " + "5/01/2018" + "\n");
System.out.println(lerpPos.x);
System.out.println(lerpPos.y);
}
This is what gets printed out into the console.
X: 0.79999995
Y: 0.75
I found some graph paper and decided to map it which was useful. I calculated the formula with a calculator and I get the same values in the x and y's lerpPos vector that is calculated in the code. I also changed it to Vector2f to make it simpler. And instead of LWJGL I decided to make a simple console program in java. While I understand it a bit more, I'm unsure how I'm supposed to use a velocity vector with the lerp function so I can give something some acceleration(?). I see how the alpha in the formula is important, but I'm unsure how to utilize it. If anything, I'd like to tryout some easing in and easing out, but the witchcraft needed seems a little bit over my head just at this moment. Oh well, I'll keep trying.
I'm going to post my completed code to my github, I'll post a link here when I get it up and running .Again, any help would be much appreciated
UPDATE:
public class Player {
private TexturedModel model;
public Vector3f position;
public Vector3f velocity;
public Vector3f acceleration;
public static Vector3f direction;
public static float maxVelocity = 0.5f;
private float rotX, rotY, rotZ;
private float scaleX, scaleY, scaleZ;
private float maxHolder;
public Player(TexturedModel model, Vector3f position, float rotX, float rotY, float rotZ,
float scaleX, float scaleY, float scaleZ) {
this.model = model;
this.rotX = rotX;
this.rotY = rotY;
this.rotZ = rotZ;
this.scaleX = scaleX;
this.scaleY = scaleY;
this.scaleZ = scaleZ;
this.position = position;
Random random = new Random();
position = new Vector3f();
velocity = new Vector3f();
acceleration = new Vector3f();
direction = new Vector3f();
}
public void update() {
velocity = velocity.add(acceleration);
position = position.add(velocity);
maxHolder = maxVelocity;
//position.length()
//Limit
if (velocity.length() > maxVelocity) {
velocity = velocity.normalize().scale(maxVelocity);
}
else if (velocity.dot(direction) < 0.0) {
velocity = new Vector3f(0,0,0);
}
}
public void movePlayer() {
if (KeyboardInput.isKeyDown(GLFW_KEY_D)) {
this.acceleration.x = 0.001f;
}
if (KeyboardInput.isKeyDown(GLFW_KEY_A)) {
this.acceleration.x = -0.001f;
}
if (KeyboardInput.isKeyDown(GLFW_KEY_W)) {
this.acceleration.y = 0.001f;
}
if (KeyboardInput.isKeyDown(GLFW_KEY_S)) {
this.acceleration.y = -0.001f;
}
if (!KeyboardInput.isKeyDown(GLFW_KEY_W) && !KeyboardInput.isKeyDown(GLFW_KEY_S) && !KeyboardInput.isKeyDown(GLFW_KEY_D) && !KeyboardInput.isKeyDown(GLFW_KEY_A)){
this.velocity.x = 0;
this.velocity.y = 0;
this.velocity.z = 0;
this.acceleration.x = 0f;
this.acceleration.y = 0;
this.acceleration.z = 0;
}
}
public void applyForce(Vector3f force) {
acceleration = force;
}
public void increasePosition(float dx, float dy, float dz) {
this.velocity.x += dx;
this.velocity.y += dy;
this.velocity.z += dz;
}
public void increaseRotation(float dx, float dy, float dz) {
this.rotX += dx;
this.rotY += dy;
this.rotZ += dz;
}
public TexturedModel getModel() {
return model;
}
public void setModel(TexturedModel model) {
this.model = model;
}
public void setVelocity(Vector3f velocity) {
this.velocity = velocity;
}
public Vector3f getPosition() {
return position;
}
public void setPosition(Vector3f position) {
this.position = position;
}
public float getRotX() {
return rotX;
}
public void setRotX(float rotX) {
this.rotX = rotX;
}
public float getRotY() {
return rotY;
}
public void setRotY(float rotY) {
this.rotY = rotY;
}
public float getRotZ() {
return rotZ;
}
public void setRotZ(float rotZ) {
this.rotZ = rotZ;
}
public float getScaleX() {
return scaleX;
}
public void setScaleX(float scaleX) {
this.scaleX = scaleX;
}
public float getScaleY() {
return scaleY;
}
public void setScaleY(float scaleY) {
this.scaleY = scaleY;
}
public float getScaleZ() {
return scaleZ;
}
public void setScaleZ(float scaleZ) {
this.scaleZ = scaleZ;
}
}
Heres the current code: It accelerates but velocity snaps back to 0 as I let go of the key. I want it to decelerate. Conceptually it should be easy.
I am having problems with my homework assignment. I created a Circle class but i'm getting some errors while using the setX and setY methods. that i don't know how to fix. My code is below. Thank you.
import java.awt.Point;
public class Circle {
private Point origin;
private double radius;
public Circle(Point o, double r)
{
setOrigin(o);
setRadius(r);
}
public Circle(double xValue, double yValue, double r)
{
origin.setX(xValue);
origin.setY(yValue);
setRadius(r);
}
public Circle()
{
setX(0.0);
setY(0.0);
setRadius(1);
}
public Circle(Circle c)
{
setOrigin(c.getOrigin());
setRadius(c.getRadius());
}
Point getOrigin()
{
return new Point(origin);
}
public void setOrigin(Point p)
{
origin.setX(p.getX());
origin.setY(p.getY());
}
public void setX(double value)
{
origin.setX(value);
}
public double getX()
{
return origin.getX();
}
public void setY(double value)
{
origin.setY(value);
}
public double getY()
{
return origin.getY();
}
public void setRadius(double value)
{
radius = value;
}
public double getRadius()
{
return radius;
}
public double getArea()
{
return (radius * radius) * Math.PI;
}
public String toString()
{
return "(" + origin.getX() + ", " + origin.getY() + ", " + radius + ")";
}
public boolean equals(Circle c)
{
if (origin.getX() == c.getX() && origin.getY() == c.getY() &&
getRadius() == c.getRadius())
{
return true;
}
else
{
return false;
}
}
public boolean doesOverlap(Circle oC)
{
double distance = Math.sqrt((Math.pow(getX() - oC.getX(), 2) + Math.pow(getY()-oC.getY(), 2)));
if ((radius + oC.radius) > distance)
{
return true;
}
else
{
return false;
}
}
}
public class Point {
private double x;
private double y;
public Point(double xValue, double yValue)
{
x = xValue;
y = yValue;
}
public Point(Point p) {
this(p.x, p.y);
}
public Point() {
this(0, 0);
}
public void setX(double xValue)
{
x = xValue;
}
public double getX()
{
return x;
}
public void setY(double xValue)
{
y = xValue;
}
public double getY()
{
return y;
}
public boolean equals(Point otherPoint)
{
return (this.x == otherPoint.x) && (this.y == otherPoint.y);
}
public String toString() {
return "(" + x + ", " + y + ")";
}
}
Have a look at the API of Point. There are no such methods like setX(...)
Additionally, I think you should initialize it especially in your second and third constructor
public Circle(double xValue, double yValue, double r){...}
public Circle(){...}
via
origin = new Point();
I have array list of circles, whitch are drawing by canvas. And everything is OK. But I need change all X,Y coordinates of circles, by during the program.
static ArrayList<Circle> mCircles;
private static void createCircles() {
if (mCircles == null) {
mCircles = new ArrayList<Circle>();
}
int rana = 66/(koeficient);
mCircles.add(new Circle(80, 200, rana));
}
public static void AddCircle() {
int rana = 66/(koeficient);
mCircles.add(new Circle(80, 200, rana));
}
private void Drawing(Canvas canvas) {
for (Circle c : mCircles) {
canvas.drawCircle(c.getCurrentX(), c.getCurrentY(), c.getRadius(),
mMalovani);
}
}
public static Circle findCircleClosestToTouchEvent(float x, float y) {
Circle c = mCircles.get(mCircles.size() - 1);
return c;
}
public class Circle extends Shape {
final float mRadius;
public Circle(float x, float y, float r) {
super(x, y);
mRadius = r;
}
final float getRadius() {
return mRadius;
}
}
public class Shape extends Activity {
protected float mStartX = 0f;
protected float mStartY = 0f;
public float mCurrentX = 30f;
public float mCurrentY = 30f;
protected float mActionDownX;
protected float mActionDownY;
protected float mActionMoveOffsetX;
protected float mActionMoveOffsetY;
// x y coordinate of a move action
public Shape (float x, float y) {
mStartX = x;
mStartY = y;
mCurrentX = x;
mCurrentY = y;
}
public void setStartX(float x) { mStartX = x; }
public void setStartY(float y) { mStartY = y; }
public float getCurrentX() { return mCurrentX; }
public float getCurrentY() { return mCurrentY; }
public void setCurrentX(float x) { mCurrentX = x;
}
public void setCurrentY(float y) { mCurrentY = y; }
public void setActionMoveOffsetX(float x) { mActionMoveOffsetX = x; }
public void setActionMoveOffsetY(float y) { mActionMoveOffsetY = y; }
public float getActionMoveOffsetX() { return mActionMoveOffsetX; }
public float getActionMoveOffsetY() { return mActionMoveOffsetY; }
public void setActionDownX(float x) { mActionDownX = x; }
public void setActionDownY(float y) { mActionDownY = y; }
public float getActionDownX() { return mActionDownX; }
public float getActionDownY() { return mActionDownY; }
public void restoreStartPosition() {
mCurrentX = mStartX;
mCurrentY = mStartY;
}
}
Assuming you have setCurrentX and setCurrentY methods opposite the getter methods, just loop through the list of circles.
private void changeCoordinates(List<Circle> circles, int x, int y){
for(Circle c:circles){
c.setCurrentX(x);
c.setCurrentY(y);
}
}