Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions src/main/java/com/thealgorithms/geometry/LineIntersection.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.thealgorithms.geometry;

/**
* Utility class to check if two line segments intersect.
*
* <p>This class provides methods to determine whether two given line segments
* intersect or not, using orientation tests.
*
* <p>Time Complexity: O(1)
*
* @author Sandeep
*/
public final class LineIntersection {

private LineIntersection() {
}

/**
* Represents a point in 2D space.
*/
public static final class Point {
public final double x;
public final double y;

public Point(double x, double y) {
this.x = x;
this.y = y;
}
}

private static int orientation(Point p, Point q, Point r) {
double val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
if (val == 0.0) {
return 0; // collinear
}
return (val > 0.0) ? 1 : 2; // clockwise or counterclockwise
}

private static boolean onSegment(Point p, Point q, Point r) {
return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x)
&& q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
}

/**
* Checks whether two line segments (p1,q1) and (p2,q2) intersect.
*
* @param p1 starting point of first segment
* @param q1 ending point of first segment
* @param p2 starting point of second segment
* @param q2 ending point of second segment
* @return true if the segments intersect, false otherwise
*/
public static boolean doIntersect(Point p1, Point q1, Point p2, Point q2) {
int o1 = orientation(p1, q1, p2);
int o2 = orientation(p1, q1, q2);
int o3 = orientation(p2, q2, p1);
int o4 = orientation(p2, q2, q1);

if (o1 != o2 && o3 != o4) {
return true;
}

if (o1 == 0 && onSegment(p1, p2, q1)) return true;
if (o2 == 0 && onSegment(p1, q2, q1)) return true;
if (o3 == 0 && onSegment(p2, p1, q2)) return true;
if (o4 == 0 && onSegment(p2, q1, q2)) return true;

return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.thealgorithms.geometry;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class LineIntersectionTest {

@Test
void testIntersectingSegments() {
LineIntersection.Point p1 = new LineIntersection.Point(1, 1);
LineIntersection.Point q1 = new LineIntersection.Point(4, 4);
LineIntersection.Point p2 = new LineIntersection.Point(1, 4);
LineIntersection.Point q2 = new LineIntersection.Point(4, 1);
assertTrue(LineIntersection.doIntersect(p1, q1, p2, q2));
}

@Test
void testNonIntersectingSegments() {
LineIntersection.Point p1 = new LineIntersection.Point(1, 1);
LineIntersection.Point q1 = new LineIntersection.Point(2, 2);
LineIntersection.Point p2 = new LineIntersection.Point(3, 3);
LineIntersection.Point q2 = new LineIntersection.Point(4, 4);
assertFalse(LineIntersection.doIntersect(p1, q1, p2, q2));
}

@Test
void testCollinearOverlappingSegments() {
LineIntersection.Point p1 = new LineIntersection.Point(1, 1);
LineIntersection.Point q1 = new LineIntersection.Point(5, 5);
LineIntersection.Point p2 = new LineIntersection.Point(2, 2);
LineIntersection.Point q2 = new LineIntersection.Point(6, 6);
assertTrue(LineIntersection.doIntersect(p1, q1, p2, q2));
}
}
Loading