I am trying to understand the Rectangle Class and MyCircle class, specifically the containsPoint methods in each one.
Here is the code:
public class MyRectangle extends GridItem {
private int height;
private int width;
public MyRectangle(int xValue, int yValue, int w, int h) {
x = xValue;
y = yValue;
width = w;
height = h;
}
public double getArea() {
return height * width;
}
public boolean containsPoint(int xValue, int yValue)
{
return xValue >= x &&
xValue <= x + width &&
yValue >= y &&
yValue <= y + height;
}
}
The confusion I'm having is, what does the containsPoint method mean?
How was this current code set up in this particular way, since isn't that supposed to return a boolean and not data types of the int?
Same dilemma for the MyCircle class.
public class MyCircle extends GridItem {
private int radius;
public MyCircle(int xValue, int yValue, int r)
{
x = xValue;
y = yValue;
radius = r;
}
public double getArea() {
return Math.PI * Math.pow(radius, 2);
}
public boolean containsPoint(int xValue, int yValue) {
double dx = x - xValue;
double dy = y - yValue;
double distance = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
return distance <= radius;
}
}
What exactly are they meaning by the containsPoint method?
How do you interpret this?
Been stumped for days and this is part of a bigger assignment, but cannot comprehend the containsPoint method so it's affect the development of mySquare class.....
So far I've got this..
public class MySquare extends GridItem
{
private int side;
public MySquare(int xValue, int yValue, int s)
{
x = xValue;
y = yValue;
side = s;
}
#Override
public double getArea()
{
return side*side;
}
#Override
public boolean containsPoint(int xValue, int yValue)
{
return x && y;
}
}
How does one apply the containsPoint method in the Square class?
Thanks!
what does the containsPoint method mean?
The method just checks if the given point (the given x,y coordinates i.e. xValue, yValue) is within the current Square or Rectangle.
How was this current code set up in this particular way, since isn't that supposed to return a boolean and not data types of the int?
The method arguments are int because they indicate the x and y coordinates for the given point.
Been stumped for days and this is part of a bigger assignment, but cannot comprehend the containsPoint method so it's affect the development of mySquare class.....
Your sub-classes such as the Sqaure class is supposed to have a set of attributes such as x, y, width, height which indicates the position and size of the square. Based on this set of attributes, check if any given point (xValue, yValue) is within your current square. The same applies for Rectangle class.
The containsPoint is the method to check if a point is inside a specific rectangle / circle / shapes on 2D plane.
Comparing variables with each other will result in an boolean value.
Each comparison in containsPoint() in MyRectangle yields a boolean value which are then connected via and. This means that it will only return true if every single comparison yields true.
You would need to apply the same principle to MySquare.
Think about how the coordinates of the square compare to the coordinates of a point if the point is inside the square.
Let's consider the containsPoint of Rectangle.
Let's assume you have a rectangle of height 2 and width 3 starting at co-ordinate (1,1). So your rectangle would look like this
(1,3) (4,3)
------------
| |
| |
------------
(1,1) (4,1)
(In the above example) given two points xValue and yValue, containsPoint returns true if
xValue is between 1 and 4 (inclusive) and
yValue is between 1 and 3 (inclusive)
and false otherwise
Thus, containsPoint tells whether a given point lies on/within a shape.
The containsPoint method of a circle also does the same thing (whether a point lies within/on the circle), however the formula is a bit more involved. You can refer to the Euclidean distance for two dimensions to understand it better.
The containsPoint for a Square will be very similar to that of a rectangle except for using width and heigth, you would have only one side.
return xValue >= x &&
xValue <= x + side &&
yValue >= y &&
yValue <= y + side;
Related
when shooting (slow) bullets in my Java game, they move at incorrect angles, however when sped up they become more and more accurate.
My x, y, speed and directions are all int, however I've tried converting to floats for more accuracy but I'm still having the same error. I believe it's happening because the lowest movement steps I can have are in integers like (+2x and +1y a step and not +1.7x and +0.88y - and I can't be on 0.5 of a pixel)
How do I 'microstep' the bullets to shoot them on the correct angle?
The only other solution I can think of to shoot them at the correct angle is to calculate the end collision point and step towards that point.
Desired behavior is for bullets to shoot at the correct angle (player to mouse) rather then at 'off' angles based on the bullets speed.
public class Bullet extends GameObject
{
private int x;
private int y;
private int speed = 2;
private int direction;
private int length = 70;
public Bullet(int x, int y, int direction)
{
this.x = x;
this.y = y;
this.direction = direction; //Set the direction.
}
public void update(Game game, GameController gc, float dt)
{
x += GameController.lengthdir_x(speed, direction);
y += GameController.lengthdir_y(speed, direction);
}
public void render(Game game, Renderer r)
{
//Draw the bullet with the tail behind it.
r.drawLine(x, y, x + GameController.lengthdir_x(length, direction - 180), y + GameController.lengthdir_y(length, direction - 180), color);
r.drawText("Dir: " + direction, x + 50, y + 20, 0xff0077ff); //Draws the players angle.
}
}
Lengthdir Code: (The angle calculates correctly as I can draw a line between two points perfectly, just when I add movement it messes up)
public static int lengthdir_x(int len, int dir)
{
return (int) (len * Math.cos(Math.toRadians(dir - 90)));
}
public static int lengthdir_y(int len, int dir)
{
return (int) (len * Math.sin(Math.toRadians(dir - 90)));
}
I've also tried doubles for variables: https://pastebin.com/fbrF17bD
Example: http://puu.sh/x9OnN/be4e3f2c80.png
The long blue line is from the player to the mouse, the yellow lines are bullets which are at the correct angle it was shot at - but not travelling the correct direction which should be exactly on the blue line. This was at a bullet speed of 2 - if the bullets are at a speed of 20, they are much closer to the blue line as per the next img: http://puu.sh/x9OwY/a54f201c91.png
I got your Problem: you use Integer-cast on the calculation result, that means you just remove everything after ., so if you get 1.9 as result you will return 1 as length. If you increase speed this error will be reduced, thats why you get better result for higher speed. You need to round your result before you return it. On the other hand you should really change to double. In the code you shown where you use double you didn't changed it in length-function, thats why you don't get better result using double. So your code should look like this:
public static double lengthdir_x(int len, int dir)
{
//don't cast here to int!!!!
return len * Math.cos(Math.toRadians(dir - 90));
}
public class Bullet extends GameObject
{
private double x;
private double y;
private int speed = 2;
private int direction;
private int length = 70;
public Bullet(double x, double y, int direction)
{
this.x = x;
this.y = y;
this.direction = direction; //Set the direction.
}
public void update(Game game, GameController gc, float dt)
{
x += GameController.lengthdir_x(speed, direction);
y += GameController.lengthdir_y(speed, direction);
}
public void render(Game game, Renderer r)
{
//Draw the bullet with the tail behind it.
r.drawLine((int)Math.round(x), (int)Math.round(y), x + GameController.lengthdir_x(length, direction - 180), y + GameController.lengthdir_y(length, direction - 180), color);
r.drawText("Dir: " + direction, (int)x + 50, (int)y + 20, 0xff0077ff); //Draws the players angle.
}
}
Maybe you will need to convert something to int or double somewhere, but make sure lengthdir returns double as result or at least (int)Math.round(...)
I've got a function that grabs the players X co-ords and then returns them, but its returning null for some reason I can't quite figure out. (Hence why I'm here).
The exact error I get is as follows:
java.lang.NullPointerException
at dev.colors.level.Level.getXOffset(Level.java:78)
All i do is call this, this is line 78:
if(player.getX() <= half_width){
This line come from this method:
public int getXOffset(){
int offset_x = 0;
//the first thing we are going to need is the half-width of the screen, to calculate if the player is in the middle of our screen
int half_width = (int) (Game.WINDOW_WIDTH/Game.SCALE/2);
//next up is the maximum offset, this is the most right side of the map, minus half of the screen offcourse
int maxX = (int) (map.getWidth()*32)-half_width;
//now we have 3 cases here
if(player.getX() <= half_width){
//the player is between the most left side of the map, which is zero and half a screen size which is 0+half_screen
offset_x = 0;
}else if(player.getX() > maxX){
//the player is between the maximum point of scrolling and the maximum width of the map
//the reason why we substract half the screen again is because we need to set our offset to the topleft position of our screen
offset_x = maxX-half_width;
}else{
//the player is in between the 2 spots, so we set the offset to the player, minus the half-width of the screen
offset_x = (int) (player.getX()-half_width);
}
return offset_x;
}
The getX method is here:
public abstract class LevelObject {
protected float x;
public LevelObject(float x, float y) {
System.out.println(x);
this.x = x;
this.y = y;
public float getX() {
System.out.println(this.x);
return x;
}
}
We declare LevelObject by creating a Player object:
player = new Player(128, 64);
Which then hands the two variables delcared there through the Player.java class, and then through the Character.java class:
public class Player extends Character {
public Player(float x, float y) throws SlickException {
super(x, y);
}
Character.java:
public abstract class Character extends LevelObject {
public Character(float x, float y) throws SlickException {
super(x, y);
}
}
Everything goes through properly up until we call getX (in the LevelObject class, even when I use the System.out to print "this.x" from LevelObject before we call getX it returns the correct variable, "128.0" as declared by the Player object.
To make things weirder, if i put some printlines inside the getX method, they don't show up in the console. It's as if it doesn't even run the method.
This doesn't make any sense to me, and I'm very very lost.
Apparently, the player variable is null.
The getXOffset() does not initialize a player variable, so I guess it must be a class field or something, which must be initialized in a different method.
Perhaps you need to add the this keyword to player initialization code (make it look like this.player = new Player(128, 64);) ?
Either way, your player variable is not initialized properly and that is the reason for that exception.
Alright, I'm trying to do some simple object moving in the direction of where you touched the screen.
If I touch directly northwest of the object, it'll kind of move into the direction of the touch position. If I touch directly southeast of the object, it will kind of move into the direction of the touch position as well. However, if I touch directly northeast of the object, it'll move into the opposite direction towards the southwest. If I touch directly southwest of the object, it'll also move to the opposite direction towards northeast.
Also, if I touch north of the object, but just a little to the west, it will go straight west with a little to the north. Same with touching west of the object with a little bit to the north, it'll go straight north with a little bit to the west. Same thing for other directions.
Really, all the directions are from somewhat to obviously incorrect. I've been doing some paper calculations as well and I've seemed to be getting some correct angles, but at this point I'm completely stumped.
Does anyone know what the problem may be?
package com.badlogic.androidgames.texasholdem;
import java.util.List;
import android.util.FloatMath;
import com.badlogic.androidgames.framework.Game;
import com.badlogic.androidgames.framework.Graphics;
import com.badlogic.androidgames.framework.Input.TouchEvent;
import com.badlogic.androidgames.framework.Screen;
public class MainMenuScreen extends Screen {
public static float TO_RADIANS = (1 / 180.0f) * (float) Math.PI;
public static float TO_DEGREES = (1 / (float) Math.PI) * 180;
float num_x = 0; // Position of object on X axis
float num_y = 0; // Position of object on Y axis
float angle = 0;
public MainMenuScreen(Game game) {
super(game);
}
public void update(float deltaTime) {
Graphics g = game.getGraphics();
List<TouchEvent> touchEvents = game.getInput().getTouchEvents();
game.getInput().getKeyEvents();
int len = touchEvents.size();
for(int i = 0; i < len; i++) {
TouchEvent event = touchEvents.get(i);
if(event.type == TouchEvent.TOUCH_UP) {
if(inBounds(event, 0, 0, g.getWidth(), g.getHeight()) ) {
// Calculate the angle of the direction between two points
angle = (float) Math.atan2(event.x - num_x, event.y - num_y) * TO_DEGREES;
if (angle < 0)
angle += 360;
// This is just to give me numbers on the Math.atan2 result, angle, to/from X position, and to/from Y position
System.out.println("Pressed! - ATAN: " + Math.atan2(event.x - num_x, event.y - num_y)
+ " - ANGLE:" + angle + " - POS: " + event.x + "tx/"
+ (int)num_x + "fx " + event.y + "ty/" + (int)num_y + "fy");
}
}
}
// Moving object in direction at 1f speed
num_x += (1f * (float) Math.cos(angle * TO_RADIANS));
num_y += (1f * (float) Math.sin(angle * TO_RADIANS));
}
private boolean inBounds(TouchEvent event, int x, int y, int width, int height) {
if(event.x > x && event.x < x + width - 1 &&
event.y > y && event.y < y + height - 1)
return true;
else
return false;
}
public void present(float deltaTime) {
Graphics g = game.getGraphics();
g.drawPixmap(Assets.background, 0, 0);
g.drawPixmap(Assets.backcard, (int)num_x, (int)num_y);
}
public void pause() {
Settings.save(game.getFileIO());
}
public void resume() {
}
public void dispose() {
}
}
if event x> x then x must be positive to move toward event.x
the problem here is that when event.x< x then your moving x must be negative
int dx,dy;
dx = (1f * (float) Math.cos(angle * TO_RADIANS));
dy = (1f * (float) Math.sin(angle * TO_RADIANS));
if(event.x<x){
dx=-dx;}
if(event.y<y){
dy=-dy;}
num_x+=dx;
num_y+=dy;
this way is simpler but less precise....
public void update(){
//(find dif between item x, and touch x)
float xdif=destx-x;
float ydif=desty-y;
if(x<destx){
dx=xdif/8;
}
else if(x>destx){
//we devide both x and y differences by the same number
dx=xdif/8;
}
else if(x==destx){
dx=0;
}
if(y<desty){
dy=ydif/5;
}
else if(y>desty){
dy=ydif/5;
}
else if(y==desty){
dy=0;
}
x+=dx;
y+=dy;
there u go, pathing in a straight line between two points, item.x and touch x.
Firstly, the math - I think the problem is that, for example, tan(135deg) = tan (-45deg) = -1. Therefore, atan has return values ranging between -90deg and 90deg as a resolution to ambiguity (look at its graph here). I think La5t5tarfighter's solution - negating the x movement in some cases - is on the right track, but you need to negate the y component in those cases as well. You could try that, but it would be much simpler if you used libGDX's Vector2 class. This is how I'd do it:
move.set(touchX, touchY); // y should be through flipping or unproject() before this
move.sub(objectPos); // move now points from object to where you touched
move.nor(); // now 1 unit long
move.scl(SPEED*deltaTime); // multiplied by a constant and delta - framerate-independent
objectPos.add(move);
You could even chain it into just one line if you want:
objectPos.add(move.set(x,y).sub(objectPos).nor().scl(SPEED*deltaTime));
Secondly, you're not using a Camera. I'm not completely sure what the default coordinate system is, but I believe the y axis points up which is not the same as the one used for inputs - Input.getY() is given with an y axis pointing down from the top left corner. If you had a Camera, you'd do this:
cam.unproject(someVector.set(Gdx.input.getX(), Gdx.input.getY(), 0));
Lacking that, you might need to flip the y axis:
event.y = Gdx.graphics.getHeight() - event.y;
Still, this could be wrong. Try drawing the object right at the touch position - if I'm right in this, it'll seem mirrored vertically. If it draws correctly where you touch, ignore this part.
I want a java function where if we pass the lat,long of a object, whether that object lies inside a area. Again this Area is defined by lat,long
for example I define a area with 3 lat/long positions.( a rectangle ) and if I pass a lat/long position it should return me whether its within the rectangle.
If the area is always a rectangle, the easiest way is to compare the coordinates.
Let's assume that your rectangle is defined by its upper left (r1x: lon and r1y: lat) and lower right (r2x and r2y) corners. Your object (a point) is defined by px: lon and py: lat.
So, your object is inside the area if
px > r1x and px < r2x
and
py < r1y and py > r2y
Programatically it would be something like:
boolean isPInR(double px, double py, double r1x, double r1y, double r2x, double r2y){
if(px > r1x && px < r2x && py < r1y && py > r2y){
//It is inside
return true;
}
return false;
}
EDIT
In the case where your polygon is not a rectangle, you can use the Java.awt.Polygon Class. In this class you will find the method contains(x,y) which return true if the point with x and y coordinates is inside the Polygon.
This method uses the Ray-casting algorithm. To simplify, this algorithm draw a segment in a random direction from your point. If the segment cross your polygon's boarder an odd number of times, then it is inside your polygon. If it crosses it an even number of times, then it is outside.
To use the polygon Class, you can do something like:
//This defines your polygon
int xCoord[] = {1,2,3,5,9,-5};
int yCoord[] = {18,-32,1,100,-100,0};
myPolygon = new Polygon(xCoord, yCoord, xCoord.length);
//This finds if the points defined by x and y coordinates is inside the polygon
Boolean isInside = myPolygon.contains(x,y);
And don't forget to
import java.awt.Polygon;
EDIT
Right coordinates are in Double !
So you need to use Path2D.Double !
Begin by import java.awt.geom.Path2D;
Let's say you start with similar arrays as before:
//This defines your polygon
Double xCoord[] = {1.00121,2,3.5464,5,9,-5};
Double yCoord[] = {18.147,-32,1,100,-100.32,0};
Path2D myPolygon = new Path2D.Double();
//Here you append all of your points to the polygon
for(int i = 0; i < xCoord.length; i++) {
myPolygon.moveTo(xCoord[i], yCoord[i]);
}
myPolygon.closePath();
//Now we want to know if the point x, y is inside the Polygon:
Double x; //The x coord
Double y; //The y coord
Boolean isInside = myPolygon.contains(x,y);
And here you go with Double !
Can someone please tell me what's wrong with this simple program? I'm getting output as "0".
package myConst;
public class Doconstructor
{
int length,width;
Doconstructor(int x, int y)
{
int area;
area = length * width;
System.out.println("area ="+area);
}
}
class work
{
public static void main(String args[])
{
Doconstructor d1 = new Doconstructor(10, 15);
}
}
Doconstructor d1 = new Doconstructor(10, 15);
// you are assigning values for x and y
But
Doconstructor (int x,int y)
{
int area; // you are never use x and y values for calculation
area = length *width; // so area remain 0 since current length and width is 0
System.out.println("area ="+area);
}
You need to change your code as follows.
Doconstructor (int x,int y)
{
int area;
this.length=x;
this.width=y;
area = length *width;
System.out.println("area ="+area);
}
Edit like this:-
package myConst;
public class Doconstructor
{
int length,width;
Doconstructor(int x, int y)
{
int area;
this.length=x;//Using this for current object
this.width=y;//Using this for current object
area = length * width;
System.out.println("area ="+area);
}
}
class work
{
public static void main(String args[])
{
Doconstructor d1 = new Doconstructor(10, 15);
}
}
Your output will be:
area =150
Must read this :
http://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
You are not setting the values of length and width and by default they are both 0. You might have to do this:
Doconstructor(int x, int y){
int area;
area = x * y;
length = x;
width = y;
System.out.println("Area = "+area);
}
You're not using the variable values you pass to the constructor in it but rather the length and width values that have been initialized to 0. You want area = x * y; instead.
The length and width fields are implicitly initialized to 0. Multiply them and you get 0.
I think what you want is
length = y ;
width = x ;
int area = length * width ;
System.out.println("area ="+area);
You have this:
public class Doconstructor {
int length,width;
Doconstructor (int x,int y)
{
int area;
area = length *width;
System.out.println("area ="+area);
}
}
At no point do you set length or width equal to anything. Their initial values are 0 and your program is doing precisely what you told it to do. area = length * width = 0 * 0 = 0.
You also are not doing anything with the x or y that you passed to the constructor, but this probably was not your intention. When writing programs, you basically need to clearly instruct the computer to do what you want to do. It's not going to guess what you want. If you ignore x and y, and don't assign any values to length or width, then that is precisely what will happen and you cannot be surprised when you see the results you see.
you are writing int length,width at class level so length and width are set to 0 as default.
After that in the constructor you are not setting any values to length and width so you are the values for length and width are 0.Hence area is also 0
Please check this link for list of default values
Constructors are used to create objects and to set the attributes. You are not setting the attributes in your constructor. Here is how your constructor should look like.
Doconstructor(int x, int y){
length = x;
width = y;
}
Secondly you are mixing the logic of a constructor and a method. You are doing the calculation of area, which seems to be a perfect fit for another method in your class. so better move that logic in a separate method:
public int calculateArea() {
int area;
area = x * y;
return area;
}
Finally create an object using constructor to set the attributes length and width. And then call calculateArea method to do the business logic of calculating area.
public static void main(String args[]){
Doconstructor d1 = new Doconstructor(10, 15); // create object and set length & width
d1.calculateArea();
}
you are not assigning the value of x and y to the variables width and length. The default value of width and length are (int) 0. Thats why you are getting the output (0*0=0). First assign the values to the variables or use "area=x*y;" .