How to check for Shape intersection using GeneralPath? Java - java

I have a program that allows you to move various Shapes about. I want to be able to return a boolean that returns true if two shapes are intersecting. This is what I have thus far:
public boolean overlaps(MyShape s){
Rectangle2D.Double otherShapeBoundary
= new Rectangle2D.Double(s.getX(), s.getY(), s.getWidth(), s.getHeight());
PathIterator pi = path.getPathIterator(null);
return path.intersects(pi,otherShapeBoundary);
}
...where path is a GeneralPath (these are all straight from the API, except MyShape).
One thing I'm unsure on is how PathIterator works, which might be the problem. I've also tried this, but I was getting a similar error:
public boolean overlaps(OverlappableSceneShape s){
Rectangle2D.Double otherShapeBoundary
= new Rectangle2D.Double(s.getX(), s.getY(), s.getWidth(), s.getHeight());
return path.intersects(otherShapeBoundary);
}
The error is that this method almost always returns false. I'm unsure when/why it is returning true, but it is very infrequent.

What I tried second was actually the correct answer. Just to be clear:
public boolean overlaps(OverlappableSceneShape s){
Rectangle2D.Double otherShapeBoundary
= new Rectangle2D.Double(s.getX(), s.getY(), s.getWidth(), s.getHeight());
return path.intersects(otherShapeBoundary);
}
is the best method of determining intersection.

Related

How to check if Rectangle will fit inside another rectangle?

I am trying to write a method that takes two rectangle parameters, and will return true if the first rectangle fits inside the second rectangle and false if it doesn't.
import java.awt.Rectangle;
public class Square {
public static void main (String[] args) {
Rectangle rect1 = new Rectangle(0,0,100,200);
Rectangle rect2 = new Rectangle(0,0,100,200);
fitsInside(rect1, rect2);
}
public static boolean fitsInside(Rectangle rec1, Rectangle rec2) {
if (rec1.width < rec2.width && rec1.height < rec2.height) {
return true;
} else {
return false;
}
}
}
When I compile and run this code it returns nothing. Why does this not work and how I could fix it?
Your approach is right. The thing is you're not outputting your answer.
Surround the line where you call fitsInside with System.out.println(...) and it will display the result you're computing.
The function fitsInside returns a boolean variable, but you are not using its return value. Since you haven't printed anything, you didn't get the result.
Printing the result will solve your problem:
System.out.println(fitsInside(rect1, rect2));

Equivalent function to .push() in java?

I'm trying to have a dynamic array with objects inside. I need a function that is equivalent to the .push() function in Javascript but in Java. The errors occur in the pipe.push(new Pipe()) inside of the setup function.
Bird bird;
Pipe[] pipe;
boolean keyDown = false;
void setup() {
size(800, 800);
frameRate(60);
bird = new Bird();
pipe.push(new Pipe());
}
//------------------------------------------------------------
void draw() {
background(0);
bird.gravity();
bird.show();
bird.edge();
}
//-----------------------------------------------------------
void keyPressed(KeyEvent e) {
if(e.getKeyCode() == 32) {
if(keyDown == false) {
bird.jump();
keyDown = true;
}
}
}
void keyReleased() {
keyDown = false;
}
//-----------------------------------------------------------------
Arrays in Java arrays are fixed size. you have to specify the size and then cant expand them. Unfortunate to change the size you need to declare new array.
But fortunately Java provides different data structures e.g. list, set which can grow dynamically as size of increases.
eg
ArrayList<Pipe> pipes = new ArrayList();
pipes.add(new Pipe());
pipes.add(new Pipe());
for(Pipe pipe : pipes){
pipe.update();
}
Here:
pipe.push(new Pipe());
simply isnt possible in Java. In Java, an array has a fixed size. You can't dynamically add/remove slots.
If you need that, you can use List/AbstractList for example.
Beyond that, the real answer here is: don't start by assuming that Java has anything to do with JavaScript. So, when you think "let's use arrays in Java", then start by researching how Java treats arrays. Don't assume that anything there is like in JavaScript.

Check if elements of different ArrayLists share position

I am programming a probe that moves through a 2D board in Java. To do this, I have two ArrayLists of Integer that contain the path that the probe has followed. The first ArrayList contains the x-coordinate, and the second one, the y-coordinate. What I would like to do is check whether the next tile of the movement has been visited or not, this is, whether the new x-coord and the new y-coord are in the corresponding ArrayList and share the same position.That way, if the new tile has been visited, I wouldn't move there. How could I possibly do this? I have tried with indexOf and lastIndexOf, but it doesn't work as each coordinate can be repeated an indefinite number of times. I also tried .contains but it didn't work either as I need that it is contained in both arrays in a specific position.
Any help would be appreciated.
First of all Java is object oriented so you should use objects. Why are you storing a coordinate in two separate arrays?
You can define your own type:
class Position implements Comparable<Position> {
public final int x;
public final int y;
Position(int x, int y) { this.x = x; this.y; }
#Override public int compareTo(Position other) { ... }
#Override public boolean equals(Object other) { ... }
#Override public int hashCode() { ... }
}
Then with this you can do whatever you want, for example
Set<Position> visited = new HashSet<Position>();
Map<Position, Integer> visitedWithSpecificPositionInPath = new HashMap<Position, Integer();
and so on.
A pretty messy approach would be to find all indexes of matching x-coordinates and for each index found check whether the y-coordinate for the given index is equal to the y in question.
So given coordinates x, y and array lists visitedX and visitedY you could do something like this:
public static boolean isVisited(int x, int y){
for(int i = 0; i < visitedX.size(), i++){
if(visitedX.get(i) == x){
if(visitedY.get(i) == y){
return true;
}
}
}
return false;
}
But as Jack has mentioned you should reconsider your data structure as looping over the complete x-coordinates list is not very efficient (though you could reduce limits of outer for loop with usage of visitedX.indexOf(x) and visitedX.lastIndexOf(x) ).

Updating an object by Reference (Suduko)

I have a Sudoku puzzle solver that requires us to use recursion.. The problem is my boolean to check for available space is supposed to update the current position by reference and it is not. What would cause this?
public boolean solve()
{
Coordinate current = new Coordinate();
if (findEmptyGridSlot(current)) { // THE ERROR IS HERE ********** THIS IS SHOWING (0,0) STILL ******************
for (int number = 1; number <= 9; number++)
if (canPlaceNumber(current, number)) {
grid[current.getRow()][current.getColumn()] = number;
if (solve())
return true;
grid[current.getRow()][current.getColumn()] = 0;
} return false;
}else
return true;
}
private boolean findEmptyGridSlot(Coordinate coordinate)
{
boolean found = false;
try{
while (!found)
{
if (grid[coordinate.getRow()][coordinate.getColumn()] == 0)
found = true;
else
coordinate = coordinate.next(); // *****This is supposed to update the current coordinate ******
}
}catch (Exception e){
//CREATE No Empty Cells Exception
}
return found;
}
public Coordinate next()
{
Coordinate result = new Coordinate(row, column);
result.column++;
if (result.column > MAX_COORDINATE)
{
result.column = MIN_COORDINATE;
result.row++;
if (result.row > MAX_COORDINATE) result = null;
}
return result;
}
Java passes by value. This means you are getting a copy of the reference to coordinate. If you point that copy to a new object (i.e. coordinate = coordinate.next) you are only changing the local copy. Now, on the other hand, if you changed an attribute of the object your variable refers to (e.g. coordinate.x = foo or coordinate.setX(foo)) that change will be visible to the caller of your method.
jpm is correct, but I misread the first time so i'm going to try to clarity
private boolean findEmptyGridSlot(Coordinate coordinate)
A reference is passed by value. Think in these terms "coordinate" is a box that holds a piece of paper, on the piece of paper an address is written. coordinate is a box that belongs to only this method and it has its own piece of paper (many pieces of paper may have the same address written on them)
We can look in this box and 'post' things to the address written on the piece of paper, however when we say
coordinate=something
this means write on a new piece of paper the address of 'something'. Throw away the old piece of paper.
This action in no way affects the original 'house' that the first piece of paper had the address on. When my friend Jon updates his address book it doesn't matter what he writes, I still live in my house.
So, if coordinate has some easy substructure (eg x and y) you can 'post' an instruction to change x and y to be equal to the "next" one.
Or as a hack you can enclose a Coordinate inside annother object so you can post an instruction to it to change what the hack class points to
Test Code refered to in comments:
public class Test {
public static void main(String args[]){
String bareMinObject="start";
changeString(bareMinObject);
System.out.println(bareMinObject); //Prints start, change string has no effect
}
public static void changeString(String input){
String temp="end";
input=temp;
}
}

Combining shape objects to create a composite

i have a program i have to do where i have to take individual shape objects and combine them to create a final car shape. we are given premade shapes such as front tire, back tire, body, windshield, and roof and supposed to combine them into one car shape. the code already given to me is the following:
CompositeShape shape = new CompositeShape();
final double WIDTH = 60;
Rectangle2D.Double body
= new Rectangle2D.Double(0, WIDTH / 6,
WIDTH, WIDTH / 6);
Ellipse2D.Double frontTire
= new Ellipse2D.Double(WIDTH / 6, WIDTH / 3,
WIDTH / 6, WIDTH / 6);
Ellipse2D.Double rearTire
= new Ellipse2D.Double(WIDTH * 2 / 3, WIDTH / 3,
WIDTH / 6, WIDTH / 6);
shape.add(body);
shape.add(frontTire);
shape.add(rearTire);
now, i have to create the compositeShape class which is where the combining takes place, but im not sure what to do in the add(Shape) method. we were also told that we were supposed to use a pathiterator method, but we werent really taught about pathiterator or what we are supposed to do with it. Im not asking for someone to tell me what exactly to code, just some helpful starter points.
the first thing that came to my mind was something like this:
public class CompositeShape implements Shape {
Graphics2D g2;
public void add(Shape shape){
g2.draw(shape);
}
but it doesnt work because i cant instantiate a new graphics object and i get a null pointer exception. after that, im pretty much stumped as to what to do. any help would be greatly appreciated. thanks!
Probably, instead of drawing the Shape inside the add() method, you're just supposed to store the added Shape for drawing later. You could do that by giving CompositeShape some kind of collection to hold Shapes that are added, and that's all I'd put in the add() method. Beyond that, it would depend what other behavior CompositeShape is supposed to have. If you have to be able to draw a CompositeShape, then you'll probably be given an Graphics object to draw on. You won't have to create your own. Then drawing a CompositeShape would be drawing all of the Shapes that it contains.
java.awt.geom.Area can combine multiple shapes with methods add, subtract, exclusiveOr, and intersect. It's a ready-made class for CompositeShape.
It seems extremely weird that you've been asked to recreate it as "CompositeShape", because Area already does what you want.
The solution could be as simple as
class CompositeShape extends java.awt.geom.Area {}
and you're done.
Or, the fact that you've been given a hint about PathIterator, it might be that you're being encouraged to manage the added shapes in a list manually, then implement all the methods of the Shape interface in terms of iterating over the other shapes.
E.g., getBounds() needs to return the rectangular bounds of the shape, so get the rectangular bounds of the first, then use Rectangle.union to join it with the bounds of the others.
And for getPathIterator(), return a new inner class implementing PathIterator that will iterate over all the shapes in your collection, and iterate the path segments of each of their getPathIterator methods, returning each path segment.
It all sounds unnecessary in practice, since the needed class already exists. I think you should get clarification on what is wanted. Good luck.
To clarify what I said about the implementation of getPathIterator, return something like this. I didn't test this. This assumes your list is called shapes.
public PathIterator getPathIterator(final AffineTransform at, final double flatness) {
return new PathIterator() {
private PathIterator currentPathIterator;
private Iterator<Shape> shapeIterator = shapes.iterator();
{ nextShape(); }
private void nextShape() {
if (shapeIterator.hasNext()) {
currentPathIterator = shapeIterator.next().getPathIterator(at, flatness);
} else {
currentPathIterator = null;
}
}
public int getWindingRule() {
return WIND_NON_ZERO;
}
public boolean isDone() {
for (;;) {
if (currentPathIterator == null) return true;
if (!currentPathIterator.isDone()) return false;
nextShape();
}
}
public void next() {
currentPathIterator.next();
}
public int currentSegment(float[] coords) {
return currentPathIterator.currentSegment(coords);
}
public int currentSegment(double[] coords) {
return currentPathIterator.currentSegment(coords);
}
};
}

Categories