Das war nicht die FrageWas gefällt Dir an den betreffenden Methoden von java.awt.Rectangle bzw. java.awt.geom.Rectangle2D nicht?
public boolean intersects(Rectangle other) {
return minX < other.maxX && maxX >= other.minX &&
maxY >= other.minY && minY < other.maxY;
}
public Rectangle intersect(Rectangle other) {
float nMinX = Math.max(minX, other.minX), nMinY = Math.max(minY, other.minY);
float nMaxX = Math.min(maxX, other.maxX), nMaxY = Math.min(maxY, other.maxY);
if (nMinX > nMaxX || nMinY > nMaxY) {
return null;
}
return new Rectangle(nMinX, nMinY, nMaxX, nMaxY);
}
Weil mich der Algo interessiert und dieses sieht man nun mal nicht bei einer closed function??? Du suchst effektive Methoden und du wurdest auf Methoden hingewiesen. Hast Du Dir diese mal angesehen?
Oder was stört Dich an den Methoden?
Danke dir! Jetzt weis ich wie man es am effektivsten erfüllen kann.Wenn du ein Rechteck durch den minimalen und maximalen Eckpunkt beschreibst, dann:
Java:public boolean intersects(Rectangle other) { return minX < other.maxX && maxX >= other.minX && maxY >= other.minY && minY < other.maxY; } public Rectangle intersect(Rectangle other) { float nMinX = Math.max(minX, other.minX), nMinY = Math.max(minY, other.minY); float nMaxX = Math.min(maxX, other.maxX), nMaxY = Math.min(maxY, other.maxY); if (nMinX > nMaxX || nMinY > nMaxY) { return null; } return new Rectangle(nMinX, nMinY, nMaxX, nMaxY); }
Weil mich der Algo interessiert und dieses sieht man nun mal nicht bei einer closed function
So allgemein, wie die Frage gestellt ist, ist das eine falsche Antwort. Die Rechtecke könnten in der Ebene unterschiedlich gedreht sein. Wenn die Projektionen auf die X/Y Achsen sich überschneiden, könnte es doch sein, dass die Rechtecke in der Ebene sich nicht berühren, sondern nebeneinander liegen.. Damit die Antwort korrekt wäre, müsste eines der Rechtecke zwei Seiten parallel zum Koordinatensystem haben.Wenn du ein Rechteck durch den minimalen und maximalen Eckpunkt beschreibst, dann:
Java:public boolean intersects(Rectangle other) { return minX < other.maxX && maxX >= other.minX && maxY >= other.minY && minY < other.maxY; } public Rectangle intersect(Rectangle other) { float nMinX = Math.max(minX, other.minX), nMinY = Math.max(minY, other.minY); float nMaxX = Math.min(maxX, other.maxX), nMaxY = Math.min(maxY, other.maxY); if (nMinX > nMaxX || nMinY > nMaxY) { return null; } return new Rectangle(nMinX, nMinY, nMaxX, nMaxY); }
import javax.swing.*;
import java.awt.*;
import java.util.Timer;
import java.util.TimerTask;
public class Box2D {
private double[][] box1 = {
{1, 1},
{1, 2},
{2, 2},
{2, 1}
};
private double[][] box2 = {
{1.85, 1.85},
{1.85, 2.85},
{2.85, 2.85},
{2.85, 1.85}
};
private void drawBoxes(Graphics2D g2d) {
if (isIntersecting()) {
g2d.setColor(Color.RED);
} else {
g2d.setColor(Color.BLUE);
}
for (int i = 0; i < box1.length; i++) {
int j = (i + 1) % box1.length;
g2d.drawLine((int) (box1[i][0] * 100), (int) (box1[i][1] * 100), (int) (box1[j][0] * 100), (int) (box1[j][1] * 100));
}
for (int i = 0; i < box2.length; i++) {
int j = (i + 1) % box2.length;
g2d.drawLine((int) (box2[i][0] * 100), (int) (box2[i][1] * 100), (int) (box2[j][0] * 100), (int) (box2[j][1] * 100));
}
}
private void rotateBoxAtCenter(double[][] box, double degrees) {
double centerX = 0;
double centerY = 0;
for (double[] point : box) {
centerX += point[0];
centerY += point[1];
}
centerX /= box.length;
centerY /= box.length;
for (double[] point : box) {
double x = point[0] - centerX;
double y = point[1] - centerY;
point[0] = x * Math.cos(Math.toRadians(degrees)) - y * Math.sin(Math.toRadians(degrees)) + centerX;
point[1] = x * Math.sin(Math.toRadians(degrees)) + y * Math.cos(Math.toRadians(degrees)) + centerY;
}
}
private boolean isIntersecting() {
for (int i = 0; i < box1.length; i++) {
int j = (i + 1) % box1.length;
for (int k = 0; k < box2.length; k++) {
int l = (k + 1) % box2.length;
if (doIntersect(box1[i][0], box1[i][1], box1[j][0], box1[j][1], box2[k][0], box2[k][1], box2[l][0], box2[l][1])) {
return true;
}
}
}
return false;
}
private boolean doIntersect(double v, double v1, double v2, double v3, double v4, double v5, double v6, double v7) {
double a1 = v3 - v1;
double b1 = v - v2;
double c1 = a1 * (v) + b1 * (v1);
double a2 = v7 - v5;
double b2 = v4 - v6;
double c2 = a2 * (v4) + b2 * (v5);
double determinant = a1 * b2 - a2 * b1;
if (determinant == 0) {
return false;
}
double x = (b2 * c1 - b1 * c2) / determinant;
double y = (a1 * c2 - a2 * c1) / determinant;
return x >= Math.min(v, v2) && x <= Math.max(v, v2) && y >= Math.min(v1, v3) && y <= Math.max(v1, v3) && x >= Math.min(v4, v6) && x <= Math.max(v4, v6) && y >= Math.min(v5, v7) && y <= Math.max(v5, v7);
}
public Box2D() {
JFrame frame = new JFrame("Box2D");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.add(new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
drawBoxes((Graphics2D) g);
}
});
frame.setVisible(true);
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
rotateBoxAtCenter(box1, 1);
rotateBoxAtCenter(box2, 2);
frame.repaint();
}
}, 1000 * 10, 25);
}
public static void main(String[] args) {
Box2D box2D = new Box2D();
}
}
Sofern die Polygone konvex sind, geht's z. B. auch mit dem Trennungssatz.Und bei irgendwelchen anderen Gebilden (n-Polygonen) bleibt schließlich nur noch flood fill übrig (als effizientes Verfahren).
Ja, da war ja was.Sofern die Polygone konvex sind
import javax.swing.*;
import java.awt.*;
import java.util.Timer;
import java.util.TimerTask;
public class Box2D {
private double[][] box1 = {
{1, 1},
{1, 2},
{2, 2},
{2, 1}
};
private double[][] box2 = {
{1.85, 1.85},
{1.85, 2.85},
{2.85, 2.85},
{2.85, 1.85}
};
private void drawBoxes(Graphics2D g2d) {
if (isIntersecting()) {
g2d.setColor(Color.RED);
} else {
g2d.setColor(Color.BLUE);
}
for (int i = 0; i < box1.length; i++) {
int j = (i + 1) % box1.length;
g2d.drawLine((int) (box1[i][0] * 100), (int) (box1[i][1] * 100), (int) (box1[j][0] * 100), (int) (box1[j][1] * 100));
}
for (int i = 0; i < box2.length; i++) {
int j = (i + 1) % box2.length;
g2d.drawLine((int) (box2[i][0] * 100), (int) (box2[i][1] * 100), (int) (box2[j][0] * 100), (int) (box2[j][1] * 100));
}
}
private void rotateBoxAtCenter(double[][] box, double degrees) {
double centerX = 0;
double centerY = 0;
for (double[] point : box) {
centerX += point[0];
centerY += point[1];
}
centerX /= box.length;
centerY /= box.length;
double radians = Math.toRadians(degrees);
for (double[] point : box) {
double x = point[0] - centerX;
double y = point[1] - centerY;
point[0] = x * Math.cos(radians) - y * Math.sin(radians) + centerX;
point[1] = x * Math.sin(radians) + y * Math.cos(radians) + centerY;
}
}
private boolean isIntersecting() {
for (int i = 0; i < box1.length; i++) {
int j = (i + 1) % box1.length;
for (int k = 0; k < box2.length; k++) {
int l = (k + 1) % box2.length;
if (doIntersect(box1[i][0], box1[i][1], box1[j][0], box1[j][1], box2[k][0], box2[k][1], box2[l][0], box2[l][1])) {
return true;
}
}
}
return false;
}
private boolean doIntersect(double v, double v1, double v2, double v3, double v4, double v5, double v6, double v7) {
double a1 = v3 - v1;
double b1 = v - v2;
double c1 = a1 * v + b1 * v1;
double a2 = v7 - v5;
double b2 = v4 - v6;
double c2 = a2 * v4 + b2 * v5;
double determinant = a1 * b2 - a2 * b1;
if (determinant == 0) {
return false;
}
double x = (b2 * c1 - b1 * c2) / determinant;
double y = (a1 * c2 - a2 * c1) / determinant;
return x >= Math.min(v, v2) && x <= Math.max(v, v2) && y >= Math.min(v1, v3) && y <= Math.max(v1, v3) && x >= Math.min(v4, v6) && x <= Math.max(v4, v6) && y >= Math.min(v5, v7) && y <= Math.max(v5, v7);
}
public Box2D() {
JFrame frame = new JFrame("Box2D");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.add(new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
drawBoxes((Graphics2D) g);
}
});
frame.setVisible(true);
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
rotateBoxAtCenter(box1, -0.5);
rotateBoxAtCenter(box2, 1);
frame.repaint();
}
}, 1000 * 10, 25);
}
public static void main(String[] args) {
Box2D box2D = new Box2D();
}
}
ich hatte die 1.85 und 2.85 willkürlich gewählt, aber vermutlich wäre 1+(pi/4) und 2+(pi/4) für die Koords sinnvoller
private double[][] box2 = {
{1 + Math.PI / 4 * 1.125, 1 + Math.PI / 4 * 1.125},
{1 + Math.PI / 4 * 1.125, 2 + Math.PI / 4 * 1.125},
{2 + Math.PI / 4 * 1.125, 2 + Math.PI / 4 * 1.125},
{2 + Math.PI / 4 * 1.125, 1 + Math.PI / 4 * 1.125}
};
Um zu überprüfen, ob sich zwei Rechtecke überschneiden, könntest du zunächst die Koordinaten der beiden Rechtecke (z. B. durch ihre Ecken) vergleichen. Wenn die Rechtecke sich nicht überlappen, gibt es einen einfachen Test, bei dem man sicherstellt, dass die rechte Seite des ersten Rechtecks nicht links von der linken Seite des zweiten Rechtecks liegt und umgekehrt. Dasselbe gilt für die obere und untere Seite der Rechtecke.Ich suche gerade zwei effiziente Methoden, die
1. bestimmen ob sich zwei Rechtecke überschneiden
2. den Bereich (als Rechteck) der Überschneidung