haha thanks everyone. Great advice Riven
sorry for hijacking the line logic thread counterp.
p.s. I slept in my car last night
Yay for work computer!
counterp, I didn’t write these but compare speeds of these 2 methods. 1 is from the internals of the java’s rect2d
Line2D.Double line = new Line2D.Double(20,40,600,400); I chose this at random number
//should use a custom linetype to reduce casting for int
int rX=20; //how many X rect
int rY=20; //how many Y rect
int spacing=25; //you can separate this into xSpace and ySpace for non squares
public void render(Graphics g) {
g.drawLine((int)line.x1, (int)line.y1, (int)line.x2, (int)line.y2);
for(int i=0;i<rX;i++){
for(int j=0;j<rY;j++){
//if(SegmentIntersectRectangle(i*spacing,j*spacing,i*spacing+spacing,j*spacing+spacing,line.x1,line.y1,line.x2,line.y2)){
//other test to compare
if(intersectsLine(line.x1, line.y1, line.x2, line.y2,i*spacing, j*spacing, spacing, spacing)){
g.setColor(Color.red); //hit!
}else{
g.setColor(Color.white); //miss!
}
g.drawRect(i*spacing, j*spacing, spacing, spacing);
}
}
}
//could throw a few of the rectX/Y and sizes into constants of some kind to help improve efficiency a little of having to not redo multiplication.
first test
private static final int OUT_LEFT = 1;
private static final int OUT_TOP = 2;
private static final int OUT_RIGHT = 4;
private static final int OUT_BOTTOM = 8;
private static int outcode(double pX, double pY, double rectX, double rectY, double rectWidth, double rectHeight) {
int out = 0;
if (rectWidth <= 0) {
out |= OUT_LEFT | OUT_RIGHT;
} else if (pX < rectX) {
out |= OUT_LEFT;
} else if (pX > rectX + rectWidth) {
out |= OUT_RIGHT;
}
if (rectHeight <= 0) {
out |= OUT_TOP | OUT_BOTTOM;
} else if (pY < rectY) {
out |= OUT_TOP;
} else if (pY > rectY + rectHeight) {
out |= OUT_BOTTOM;
}
return out;
}
public static boolean intersectsLine(double lineX1, double lineY1, double lineX2, double lineY2, double rectX, double rectY, double rectWidth, double rectHeight) {
int out1, out2;
if ((out2 = outcode(lineX2, lineY2, rectX, rectY, rectWidth, rectHeight)) == 0) {
return true;
}
while ((out1 = outcode(lineX1, lineY1, rectX, rectY, rectWidth, rectHeight)) != 0) {
if ((out1 & out2) != 0) {
return false;
}
if ((out1 & (OUT_LEFT | OUT_RIGHT)) != 0) {
double x = rectX;
if ((out1 & OUT_RIGHT) != 0) {
x += rectWidth;
}
lineY1 = lineY1 + (x - lineX1) * (lineY2 - lineY1) / (lineX2 - lineX1);
lineX1 = x;
} else {
double y = rectY;
if ((out1 & OUT_BOTTOM) != 0) {
y += rectHeight;
}
lineX1 = lineX1 + (y - lineY1) * (lineX2 - lineX1) / (lineY2 - lineY1);
lineY1 = y;
}
}
return true;
}
2nd test
boolean SegmentIntersectRectangle(double a_rectangleMinX,
double a_rectangleMinY, double a_rectangleMaxX,
double a_rectangleMaxY, double a_p1x, double a_p1y, double a_p2x,
double a_p2y) {
// Find min and max X for the segment
double minX = a_p1x;
double maxX = a_p2x;
if (a_p1x > a_p2x) {
minX = a_p2x;
maxX = a_p1x;
}
// Find the intersection of the segment's and rectangle's x-projections
if (maxX > a_rectangleMaxX) {
maxX = a_rectangleMaxX;
}
if (minX < a_rectangleMinX) {
minX = a_rectangleMinX;
}
if (minX > maxX) // If their projections do not intersect return false
{
return false;
}
// Find corresponding min and max Y for min and max X we found before
double minY = a_p1y;
double maxY = a_p2y;
double dx = a_p2x - a_p1x;
if (Math.abs(dx) > 0.0000001) {
double a = (a_p2y - a_p1y) / dx;
double b = a_p1y - a * a_p1x;
minY = a * minX + b;
maxY = a * maxX + b;
}
if (minY > maxY) {
double tmp = maxY;
maxY = minY;
minY = tmp;
}
// Find the intersection of the segment's and rectangle's y-projections
if (maxY > a_rectangleMaxY) {
maxY = a_rectangleMaxY;
}
if (minY < a_rectangleMinY) {
minY = a_rectangleMinY;
}
if (minY > maxY) // If Y-projections do not intersect return false
{
return false;
}
return true;
}
edit:
I still can see a custom solution in my head that I feel like is way quicker and like 5 lines tops. Itd use
double m=(line.y1-line.y2)/(line.x1-line.x2);
double b = m*line.x1-line.y1;
then a return function with 4 or 8 &&|| sets of ?<x<?
I also could imagine another one, that doesn’t need to blunt force your way through ALL the rectangles(as clearly some have 0 chance of ever being in it, but by using the slope calculation, directly hit numbers in simple boolean grid[][]; So you wouldnt need a nested for loop(this should be the fastest) for detection? but a direct grid[pointY/rectHeight] = HIT;