From the image I posted up there, I have all the coordinates from those rectangles in the Figure C saved in an array of the class Figure.
Figure:
public abstract class Figure {
private int left, right, height;
protected Coordinates[] coords;
public Figure() {
}
public Figure(int left, int right, int height, Coordinates[] coords) {
this.left = left;
this.right = right;
this.height = height;
this.coords = coords;
}
public int getRight() {
return right;
}
public int getLeft() {
return left;
}
public int getHeight() {
return height;
}
public Coordinates[] getCoords() {
return coords;
}
public abstract void setCoordinates();
public abstract void showCoordinates();
}
Coordinates:
public class Coordinates {
private float x, y;
public Coordinates() {
}
public Coordinates(float x, float y) {
this.x = x;
this.y = y;
}
public float getX() {
return x;
}
public float getY() {
return y;
}
}
Thing is, I have to find the coordinates of the silhouette from the whole graph the way it is in Figure D (see the image) using the coordinates from the array already mentioned.
Example (See the Image Reference):
1st Rectangle Coordinates are: (1,0)(1,11)(5,11)(5,0)
2nd Rectangle Coordinates are: (2,0)(2,6)(7,6)(7,0)
3rd Rectangle Coordinates are: (3,0)(3,13)(9,13)(9,0)
4th Rectangle Coordinates are: (12,0)(12,7)(16,7)(7,0)
5th Rectangle Coordinates are: (14,0)(14,3)(25,3)(25,0)
6th Rectangle Coordinates are: (19,0)(19,18)(22,18)(22,0)
7th Rectangle Coordinates are: (23,0)(23,13)(29,13)(29,0)
8th Rectangle Coordinates are: (24,0)(24,4)(28,4)(28,0)
The Coordinates of the Silhouettes from all those rectangles should be:
(1,11)(3,13)(9,0)(12,7)(16,3)(19,18)(22,3)(23,13)(29,0)
This is where I'm stuck thinking how I'll get these coordinates.
I'm not asking someone to do it for me or something like that, I just want to think from where to start cause all I've tried failed so far, so any tips or ideas would come in handy! thank you so much in advance! Good nite.
It looks like you are attempting to obtain the union of each cluster of overlapping rectangles. Java's java.awt.geom.Rectangle class has a createUnion(Rectangle2D) method that will 'absorb' a second rectangle into the first (via a 'union'). However, this doesn't solve your clustering problem.
If the the number of rectangles you are trying to process is relatively small and clustering is only needed in one dimension (i.e. horizontally), the most straight-forward way would be to keep a list of rectangles that haven't already been clustered, loop through each unclustered rectangle, remove the first rectangle into its own new 'cluster' and then perform an intersect with all other unclustered rectangles to determine if the pair should be clustered. The java.awt.geom.Rectangle2D.intersects(Rectangle) method is perfectly suitable for this. If they intersect then the rectangle that intersects should be removed from the list of unclustered rectangles and added to the current cluster.
The Rectangle2D class doesn't quite match your storage of coordinates, but a mapping will be reasonably straight forward.
Once you have your sets of clustered rectangles, you still need to find the path of each Polygon that bounds all rectangles in a given cluster. If your sample picture is indicative of all rectangles such that they all have their bottom edge at the same 'height' and none of your rectangles have different rotations, this will be a lot easier.
Related
#Override
public Shape getShape() {
final Rectangle2D.Double result = new Rectangle2D.Double();
result.setFrameFromDiagonal(getStart(), getEnd());
//FIX this is causing square to move when going opposite direction
result.setRect(result.getX(), result.getY(),
result.getHeight(), result.getHeight());
return result;
}
So here is my code that is drawing a square using Rectangle2D.Double. The getStart() and getEnd() are points that are being returned from mouseDrag events. When I drag to the right or up, it works as intended and creates a square. When I drag left or down the square moves with the drag as it draws. I am fairly new to Java swing and paint components. Wondering if anyone know what is causing this and why?
You need to consider a few specialities:
Save the first coordinate on mouse click: x,y
Save the last coordinate on mouse drag x2,y2
Set min x and y coordinates as the startpoint for setRect: Math.min(x,x2);
Use the absolute value of the coordinate difference to calculate the height and width of rectangle: Math.abs(x-x2);
px = Math.min(x,x2);
int py = Math.min(y,y2);
int pw=Math.abs(x-x2);
int ph=Math.abs(y-y2);
result.setRect(px, py, pw, ph);
I am writing a code in which a circle moves randomly in a box and if it collides with any of the small rectangles inside it, it changes its heading direction/ bounces back. I am using the intersects method to find the collision between them. But the circle sometimes overlaps the rectangles rather than bouncing back on contact. I am bouncing back the ball by changing the orientation (180+current_orientation).
I am trying to solve this issue, but did not found any success yet. I read that intersects is finding the match by checking overlap of the bounding rectangles. But, how can I fix this issue. Is this problem due to the intersection or is there any issue with the way i am changing orientation. Any idea?
Code:
private void collisionAvoidanceRobot(int x, int y, int r, double robot_orientation2)
{
boolean collide1=false;
boolean collide2=false;
boolean collide3=false;
boolean collide4=false;
boolean collide5=false;
boolean collide6=false;
r+=5;
Shape collisionrobot=new Ellipse2D.Double(x,y,r,r);
collide1=collisionrobot.intersects(obst1);
if(collide1)
{
robot_orientation=180+robot_orientation;
}
collide2=collisionrobot.intersects(obst2);
if(collide2)
{
robot_orientation=180+robot_orientation;
}
collide3=collisionrobot.intersects(obst3);
if(collide3)
{
robot_orientation=180+robot_orientation;
}
collide4=collisionrobot.intersects(obst4);
if(collide4)
{
robot_orientation=180+robot_orientation;
}
collide5=collisionrobot.intersects(obst5);
if(collide5)
{
robot_orientation=180+robot_orientation;
}
collide6=collisionrobot.intersects(obst6);
if(collide6)
{
robot_orientation=180+robot_orientation;
}
}
public void setXPosition_robot(int x)
{
double distance=0;
distance = unit_moved + randomDouble(0, forwardNoise);
robot_x= (int) (x + Math.sin(Math.toRadians(robot_orientation))*distance);
//System.out.println("Robot_X:"+robot_x);
}
public void setYPosition_robot(int y)
{
double distance=0;
distance = unit_moved + randomDouble(0, forwardNoise);
robot_y=(int) (y+ Math.cos(Math.toRadians(robot_orientation))*distance);
//System.out.println("Robot_Y:"+robot_y);
}
private void createRobot(Graphics2D g)
{
ArrayList<Integer> robot_list= new ArrayList<Integer>();
robot_list=positionRobot(robot_x,robot_y);
robot_x=robot_list.get(0);
robot_y=robot_list.get(1);
setNoise(0.05,0.05,5.0);
//System.out.println("Robot:"+robot_x+"--"+robot_y+"--"+robot_orientation);
adjustRobotOrientation();
collisionAvoidanceRobot(robot_x,robot_y,robot_radius,robot_orientation);
drawRobot(g,robot_x,robot_y,robot_radius);
}
Screenshot:
Does the circle appear to wobble? since you are moving the circle a random distance each iteration, the distance that it moved into the square could be greater than the distance it gets on the next iteration to move in the opposite direction, this would cause the circle to "stick".
also, your collisionAvoidanceRobot could use a for loop instead of all those ifs
I'm working in a game with some friends in which we have a large horizontal world and a OrthographicCamera that shows only 1/3 of it. This camera it's moved when the horizontal position of the player change so the camera only move to the left and to the right.
Some of the objects showed in the game are near the player point-of-view but others are far away (for example, islands). With this in consideration, we cannot set fixed positions for elements and move only the camera. We need to achieve a parallax effect taking in consideration the distance of the elements.
Here is a simple image to explain it better:
The viewport to the left shows 3 objects of the game. The green one is near the player, the red ellipse is far and the yellow one is in the middle. In the viewport to the right the camera has been moved to the right so all the objects disappear to the left. The thing is that the relative movement of the green rectangle is greater than the movement of the yellow. In the same way, movement of yellow object is greater than red object movement.
I created all my assets scaled taking in consideration how far they are but now, how can I simulate this perspective using libGDX? Is there any class to do it? If I have to set elements position in each iteration, how could I calculate the right position?
Note that the example below is not tested as I am just recalling how I did it. The idea is simple - create layers with an extra layer for each with initial positions and velocity and move them. If a layer goes off the edge, put another one (that is why we create an extra layer) at the opposite edge.
Say you have a parallax object that takes initial positions, size, and velocity-
public class Parallax extends DynamicGameObject {
public float width, height; // Use setter/getter if you prefer
public Parallax(float x, float y, float width, float height, float velocityX, float velocityY) {
super(x, y, width, height);
velocity.set(velocityX, velocityY);
this.width = width;
this.height = height;
}
public void update(float deltaTime) {
position.add(velocity.x * deltaTime, velocity.y * deltaTime);
}
public void setPosition(float x, float y) {
position.set(x, y);
}
}
DynamicGameObject is taken from SuperJumper demo-
public class DynamicGameObject extends GameObject {
public final Vector2 velocity;
public final Vector2 accel;
public DynamicGameObject(float x, float y, float width, float height) {
super(x, y, width, height);
velocity = new Vector2();
accel = new Vector2();
}
}
GameObject as well-
public class GameObject {
public final Vector2 position;
public final Rectangle bounds;
public GameObject(float x, float y, float width, float height) {
this.position = new Vector2(x,y);
this.bounds = new Rectangle(x - width/2f, y - height/2f, width, height);
}
}
Say we have two layers - one in front and the other goes at back. We have one texture for each. Each texture fills the entire screen. We create two instances for each layer so that when one texture starts going off the screen, the other shows up at the edge to fill the gap. If you have smaller textures, you need to determine first how many textures you need to fill the screen and then create layers with one extra to fill the gap in between.
We can create an array of parallax layers during world creation-
Array<Parallax> parallaxList = new Array<Parallax>(4);
We can create the layers like this-
// Back
/* First parallax for back layer is at 0 x-axis. If you want to move the texture from right to left, the value of BACK_VELOCITY_X should be negative. You can experiment with velocity value for desire pace of movement. We do not want our layer to move on y-axis. Hence, it is set to 0. */
parallaxList.add(new Parallax(0, BACK_TEXTURE_HEIGHT, BACK_TEXTURE_WIDTH, BACK_TEXTURE_HEIGHT, BACK_VELOCITY_X, 0));
/* This one is also for back layer but it is positioned at the right edge of the layer above*/
parallaxList.add(new Parallax(BACK_TEXTURE_WIDTH, BACK_TEXTURE_HEIGHT, BACK_TEXTURE_WIDTH, BACK_TEXTURE_HEIGHT, SOME_VELOCITY_X, 0));
// Front
parallaxList.add(new Parallax(0, 0, FRONT_TEXTURE_WIDTH, FRONT_TEXTURE_HEIGHT, FRONT_VELOCITY_X, 0));
parallaxList.add(new Parallax(FRONT_TEXTURE_WIDTH, 0, FRONT_TEXTURE_WIDTH, FRONT_TEXTURE_HEIGHT, FRONT_VELOCITY_X, 0));
We update the layers on an update call in each frame-
// In our example, TOTAL_LAYERS is 4
for (int i = 0; i < TOTAL_LAYERS; i++) {
int tmpInt;
Parallax parallax = parallaxList.get(i);
parallax.update(deltaTime);
// If one layer is off the edge, put it at the right of the next one
// In this example, layers are moving from right to left
if (parallax.position.x <= -parallax.width) {
// We know that parallaxList's indexes 0 and 1 hold the back layers
// and indexes 2 and 3 have the front layers. You can add additional
// parameters in Parallax class to indicate a group so that you do not
// have to determine the group in dirty way like this
if(i == 0){
tmpInt = 1;
} else if(i == 1) {
tmpInt = 0;
} else if(i == 2) {
tmpInt = 3;
} else {
tmpInt = 2;
}
parallax.setPosition(parallaxList.get(tmpInt).position.x + parallax.width, parallax.position.y);
}
}
You can use an OrthographicCamera and a SpriteBatch to draw the parallax layers. You can actually use the game camera you have but I think using a separate camera is much cleaner. Anyways, parallax textures are usually big enough to be batched in a separate call so using the game camera most probably will not save you a draw call.
So I've implemented a movable camera using all the projection maths and things. I have some input conditions, when I hit A or D I'm meant to move left and right respectively, but I cant do that, the camera only moves on the Z axis. Not only that but when I scale by a negative number on any axis the cube I'm rendering is inverted and weird, the front face is culled instead of the ones i'm not meant to see. This issue is probably not to do with my quaternion, matrix or vector classes as I copied them from github (as well as following the youtube series connected to them).
to move left or right I use:
public void input(){
float movAmt = (float)(10 * Time.getDelta());
float rotAmt = (float)(100 * Time.getDelta());
if(Input.getKey(Input.KEY_W)){
move(getForward(), movAmt);
}
if(Input.getKey(Input.KEY_S)){
move(getForward(), -movAmt);
}
if(Input.getKey(Input.KEY_A)){
move(getLeft(), movAmt);
}
if(Input.getKey(Input.KEY_D)){
move(getRight(), movAmt);
}
if(Input.getKey(Input.KEY_UP)){
rotateX(-rotAmt);
}
if(Input.getKey(Input.KEY_DOWN)){
rotateX(rotAmt);
}
if(Input.getKey(Input.KEY_LEFT)){
rotateY(-rotAmt);
}
if(Input.getKey(Input.KEY_RIGHT)){
rotateY(rotAmt);
}
}
public void move(Vector3f dir, float amt){
pos = pos.add(dir.mult(amt));
}
public void rotateY(float angle){
Vector3f Haxis = yAxis.cross(forward);
Haxis.normalize();
forward.rotate(angle, yAxis);
forward.normalize();
up = forward.cross(Haxis);
up.normalize();
}
public void rotateX(float angle){
Vector3f Haxis = yAxis.cross(forward);
Haxis.normalize();
forward.rotate(angle, Haxis);
forward.normalize();
up = forward.cross(Haxis);
up.normalize();
}
public Vector3f getLeft(){
return forward.cross(up).normalize();
}
public Vector3f getRight(){
return up.cross(forward).normalize();
}
Where should I look to find the issue? (In general throughout the whole program)
Your question is kinda confusing to me, as I think you're talking about two things.
But when you scale with a negative value like glScalef(1f, -1f, 1f); then you need to invert the front face using glFrontFace();
Example:
// Render stuff
glPushMatrix();
glFrontFace(GL_CW);
// Render negatively scaled stuff
glFrontFace(GL_CCW);
glPopMatrix();
// Render stuff
Note: I'm only using the deprecated methods for show, so if you've created your own matrix stack then you can simply change my example to fit your code.
I don't know how to complete this. I'm learning by myself and I found this exercise where you have a class for a rectangle like this:
public class Rectangulo {
private int x, y, width, heigth;
public Rectangulo(int x, int y, int width, int heigth){
this.x = x;
this.y = y;
this.width = width;
this.heigth = heigth;
}
public boolean isOverlaping(Rectangulo r1, Rectangulo r2){
}
And I have to complete the method so it returns true if the 2 rectangles are overlapping / colliding or false if they aren't. Can you give me any guide to help me think this problem, or tips?
I don't have to use the intersects method.
Thanks!
If you look at the method, you're provided with two rectangle objects as arguments, r1 & r2. Each instance has its specific value for x,y, width and height. You can use these values to determine whether the two rectangles collide or overlap
For your specific doubt, you might want to read the javadoc for Rectangle.. This will help you understand how a rectangle is created in Java