diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..9ca6048 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml + +/compiler.xml +/modules.xml +/misc.xml +/uiDesigner.xml +/vcs.xml +/ComputationalGeometry.iml diff --git a/.idea/ComputationalGeometry.iml b/.idea/ComputationalGeometry.iml new file mode 100644 index 0000000..759a0d1 --- /dev/null +++ b/.idea/ComputationalGeometry.iml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..2c6be05 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..712ab9d --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_google_auto_value_auto_value_annotations_1_6_3.xml b/.idea/libraries/Maven__com_google_auto_value_auto_value_annotations_1_6_3.xml new file mode 100644 index 0000000..b2aae23 --- /dev/null +++ b/.idea/libraries/Maven__com_google_auto_value_auto_value_annotations_1_6_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_google_code_findbugs_jsr305_3_0_2.xml b/.idea/libraries/Maven__com_google_code_findbugs_jsr305_3_0_2.xml new file mode 100644 index 0000000..1c380d0 --- /dev/null +++ b/.idea/libraries/Maven__com_google_code_findbugs_jsr305_3_0_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_google_errorprone_error_prone_annotations_2_3_3.xml b/.idea/libraries/Maven__com_google_errorprone_error_prone_annotations_2_3_3.xml new file mode 100644 index 0000000..1c81eb0 --- /dev/null +++ b/.idea/libraries/Maven__com_google_errorprone_error_prone_annotations_2_3_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_google_guava_failureaccess_1_0_1.xml b/.idea/libraries/Maven__com_google_guava_failureaccess_1_0_1.xml new file mode 100644 index 0000000..36e948e --- /dev/null +++ b/.idea/libraries/Maven__com_google_guava_failureaccess_1_0_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_google_guava_guava_28_1_android.xml b/.idea/libraries/Maven__com_google_guava_guava_28_1_android.xml new file mode 100644 index 0000000..22e1968 --- /dev/null +++ b/.idea/libraries/Maven__com_google_guava_guava_28_1_android.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_google_guava_listenablefuture_9999_0_empty_to_avoid_conflict_with_guava.xml b/.idea/libraries/Maven__com_google_guava_listenablefuture_9999_0_empty_to_avoid_conflict_with_guava.xml new file mode 100644 index 0000000..4e15702 --- /dev/null +++ b/.idea/libraries/Maven__com_google_guava_listenablefuture_9999_0_empty_to_avoid_conflict_with_guava.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_google_j2objc_j2objc_annotations_1_3.xml b/.idea/libraries/Maven__com_google_j2objc_j2objc_annotations_1_3.xml new file mode 100644 index 0000000..bacaa45 --- /dev/null +++ b/.idea/libraries/Maven__com_google_j2objc_j2objc_annotations_1_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_google_truth_truth_1_0_1.xml b/.idea/libraries/Maven__com_google_truth_truth_1_0_1.xml new file mode 100644 index 0000000..902b2b3 --- /dev/null +++ b/.idea/libraries/Maven__com_google_truth_truth_1_0_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_googlecode_java_diff_utils_diffutils_1_3_0.xml b/.idea/libraries/Maven__com_googlecode_java_diff_utils_diffutils_1_3_0.xml new file mode 100644 index 0000000..db8944e --- /dev/null +++ b/.idea/libraries/Maven__com_googlecode_java_diff_utils_diffutils_1_3_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__junit_junit_4_13.xml b/.idea/libraries/Maven__junit_junit_4_13.xml new file mode 100644 index 0000000..59fc5c4 --- /dev/null +++ b/.idea/libraries/Maven__junit_junit_4_13.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_checkerframework_checker_compat_qual_2_5_5.xml b/.idea/libraries/Maven__org_checkerframework_checker_compat_qual_2_5_5.xml new file mode 100644 index 0000000..a4c92ee --- /dev/null +++ b/.idea/libraries/Maven__org_checkerframework_checker_compat_qual_2_5_5.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_codehaus_mojo_animal_sniffer_annotations_1_18.xml b/.idea/libraries/Maven__org_codehaus_mojo_animal_sniffer_annotations_1_18.xml new file mode 100644 index 0000000..7663451 --- /dev/null +++ b/.idea/libraries/Maven__org_codehaus_mojo_animal_sniffer_annotations_1_18.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml b/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml new file mode 100644 index 0000000..f58bbc1 --- /dev/null +++ b/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_jetbrains_annotations_22_0_0.xml b/.idea/libraries/Maven__org_jetbrains_annotations_22_0_0.xml new file mode 100644 index 0000000..f350de5 --- /dev/null +++ b/.idea/libraries/Maven__org_jetbrains_annotations_22_0_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..fecf653 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..9f0a731 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..797acea --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..e96534f --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index d48e770..a47b449 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,10 @@ computational geometry on 2D ## Problems solved in this part -1. Define point segment, ray and line. -2. Tell whether two segments intersect -3. Tell whether three points co-line +####1. Definitions +2D: point, line, ray, segment, vector +####2. Intersection +between line, ray and segment +####3. Distance + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..de6797c --- /dev/null +++ b/pom.xml @@ -0,0 +1,36 @@ + + + 4.0.0 + + groupId + ComputationalGeometry + 1.0-SNAPSHOT + + + 16 + 16 + + + + + junit + junit + 4.13 + test + + + + com.google.truth + truth + 1.0.1 + + + org.jetbrains + annotations + RELEASE + compile + + + \ No newline at end of file diff --git a/src/java/IDefinition/ILine.java b/src/java/IDefinition/ILine.java new file mode 100644 index 0000000..c07f740 --- /dev/null +++ b/src/java/IDefinition/ILine.java @@ -0,0 +1,15 @@ +package IDefinition; + +public interface ILine extends IShape{ + boolean parallel(ILine l); + + boolean pass(IPoint point); + + IShape intersect(ILine line) throws Exception; + IShape intersect(IRay ray); + IShape intersect(ISegment segment); + + IPoint getOnePassPoint(); + + IVector getDirection(); +} diff --git a/src/java/IDefinition/IPoint.java b/src/java/IDefinition/IPoint.java new file mode 100644 index 0000000..6f4accf --- /dev/null +++ b/src/java/IDefinition/IPoint.java @@ -0,0 +1,7 @@ +package IDefinition; + +import java.util.List; + +public interface IPoint extends IShape { + List toList(); +} diff --git a/src/java/IDefinition/IPolygon.java b/src/java/IDefinition/IPolygon.java new file mode 100644 index 0000000..9070cf1 --- /dev/null +++ b/src/java/IDefinition/IPolygon.java @@ -0,0 +1,13 @@ +package IDefinition; + +public interface IPolygon { + int getEdges(); + + double getPerimeter(); + double getArea(); + + IShape intersect(IPolygon polygon); + + double isSimplePolygon(); + double isConvexPolygon(); +} diff --git a/src/java/IDefinition/IRay.java b/src/java/IDefinition/IRay.java new file mode 100644 index 0000000..b0e7d0c --- /dev/null +++ b/src/java/IDefinition/IRay.java @@ -0,0 +1,16 @@ +package IDefinition; + +public interface IRay extends IShape{ + boolean parallel(IRay ray); + boolean pass(IPoint point); + + IShape intersect(IRay ray); + IShape intersect(ISegment segment); + IShape intersect(ILine line); + + IPoint getStartPoint(); + + IVector getDirection(); + + +} diff --git a/src/java/IDefinition/ISegment.java b/src/java/IDefinition/ISegment.java new file mode 100644 index 0000000..93bda08 --- /dev/null +++ b/src/java/IDefinition/ISegment.java @@ -0,0 +1,17 @@ +package IDefinition; + +import java.util.List; + +public interface ISegment extends IShape{ + + IShape intersect(ISegment segment); + IShape intersect(ILine line); + IShape intersect(IRay ray); + + IPoint[] getEnds(); + double getLength(); + + IVector getDirection(); + + boolean pass(IPoint point); +} diff --git a/src/java/IDefinition/IShape.java b/src/java/IDefinition/IShape.java new file mode 100644 index 0000000..220eb7c --- /dev/null +++ b/src/java/IDefinition/IShape.java @@ -0,0 +1,5 @@ +package IDefinition; + +public interface IShape { + double distance (IShape shape); +} diff --git a/src/java/IDefinition/ITriangle.java b/src/java/IDefinition/ITriangle.java new file mode 100644 index 0000000..6cec134 --- /dev/null +++ b/src/java/IDefinition/ITriangle.java @@ -0,0 +1,7 @@ +package IDefinition; + +public interface ITriangle extends IPolygon { + boolean isRHTriangle(); + boolean isAcute(); + boolean isObtuse(); +} diff --git a/src/java/IDefinition/IVector.java b/src/java/IDefinition/IVector.java new file mode 100644 index 0000000..8002f97 --- /dev/null +++ b/src/java/IDefinition/IVector.java @@ -0,0 +1,14 @@ +package IDefinition; + +import javax.naming.OperationNotSupportedException; + +public interface IVector { + boolean parallel(IVector vector); + double dotProduct(IVector vector); + + IVector uniform() throws OperationNotSupportedException; + double modular(); + + IVector add(IVector vector); + IVector multiply(double a); +} diff --git a/src/java/TwoD/definition/Line2D.java b/src/java/TwoD/definition/Line2D.java new file mode 100644 index 0000000..6f7835f --- /dev/null +++ b/src/java/TwoD/definition/Line2D.java @@ -0,0 +1,171 @@ +package TwoD.definition; + +import IDefinition.*; +import org.jetbrains.annotations.NotNull; + +import javax.sound.sampled.Line; + +public class Line2D implements ILine { + private final Vector2D direction; + private final Point2D passPoint; + + public Line2D(@NotNull Vector2D direction, @NotNull Point2D passPoint) { + if(direction.isZeroVector()) + throw new IllegalArgumentException("Try to initialise from a zero vector."); + this.direction = direction; + this.passPoint = passPoint; + } + + public Line2D(@NotNull Point2D p1, @NotNull Point2D p2){ + if(p1.equals(p2)) + throw new IllegalArgumentException("Try to initialise a ray from two same points."); + this.direction = new Vector2D(p1,p2); + this.passPoint = p1; + } + + @Override + public Point2D getOnePassPoint() { + return passPoint; + } + + @Override + //when l == this, return false + public boolean parallel(ILine l) { + if(l instanceof Line2D){ + return (!l.equals(this)) && ((Line2D)l).direction.parallel(direction); + } + else throw new IllegalArgumentException("Dimension not match."); + } + + @Override + public boolean pass(IPoint point) { + if(point instanceof Point2D){ + return new Vector2D(passPoint, (Point2D) point).parallel(direction); + } + else throw new IllegalArgumentException("Dimension not match."); + } + + @Override + public IShape intersect(ILine line){ + if(line instanceof Line2D){ + if(((Line2D) line).direction.parallel(direction)){ + if(!this.equals(line)) + return null; + else + return this; + } + else{ + double v_x1 = this.direction.getX(); + double v_y1 = this.direction.getY(); + + double v_x2 = ((Line2D) line).direction.getX(); + double v_y2 = ((Line2D) line).direction.getY(); + + double a1 = v_y1*passPoint.getX() - v_x1*passPoint.getY(); + double a2 = v_y2*((Line2D)line).passPoint.getX() - v_x2*((Line2D)line).passPoint.getY(); + + double d0 = v_x1*v_y2 - v_y1*v_x2; + double dx = a2*v_x1 - a1*v_x2; + double dy = v_y1*a2 - v_y2*a1; + + double x = dx/d0; + double y = dy/d0; + + return new Point2D(x,y); + } + } + else throw new IllegalArgumentException("Dimension not match."); + } + + @Override + public IShape intersect(IRay ray) { + if(ray instanceof Ray2D){ + if(ray.intersect(new Ray2D(passPoint,direction))!=null || + ray.intersect(new Ray2D(passPoint, direction.multiply(-1)))!=null){ + return this.intersect( + new Line2D( + ((Ray2D) ray).getDirection(), + ((Ray2D) ray).getStartPoint())); + } + else return null; + } + else throw new IllegalArgumentException("Dimension not match."); + } + + + @Override + public IShape intersect(ISegment segment) { + if(segment instanceof Segment2D){ + boolean intersect = segment.intersect(new Ray2D(passPoint,direction))!=null || + segment.intersect(new Ray2D(passPoint, direction.multiply(-1)))!=null; + if(intersect){ + if(this.pass(((Segment2D) segment).getP1())&&this.pass(((Segment2D) segment).getP2())) + return (Segment2D)segment; + else return this.intersect( + new Line2D( + (Vector2D) segment.getDirection(), + (Point2D) segment.getEnds()[0])); + } + else return null; + } + else throw new IllegalArgumentException("Dimension not match."); + } + + @Override + public Vector2D getDirection() { + return direction; + } + + @Override + public int hashCode() { + return this.direction.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if(obj == this) + return true; + if(obj instanceof Line2D){ + return ((Line2D) obj).direction.parallel(this.direction) && this.pass(((Line2D) obj).getOnePassPoint()); + } + else return false; + } + + @Override + public String toString(){ + return String.format("Line2D %f x %+f y = %f", + direction.getY(), + direction.getX(), + direction.getX()*passPoint.getY()-direction.getY()*passPoint.getX()); + } + + @Override + public double distance(IShape shape) { + if(shape instanceof Line2D line){ + if(this.intersect(line)!=null) + return 0; + else{ + Vector2D v = new Vector2D(this.passPoint, line.getOnePassPoint()); + Vector2D p = this.direction.computePerpendicular(); + + return Math.abs(v.dotProduct(p.multiply(1/p.modular()))); + } + } + else if (shape instanceof Ray2D){ + + //todo: finish + return 0; + } + else if(shape instanceof Point2D point){ + Vector2D v = new Vector2D(point,passPoint); + Vector2D p = this.direction.computePerpendicular(); + return Math.abs(v.dotProduct(p.multiply(1/p.modular()))); + } + + else if(shape instanceof Segment2D){ + return 0; + //todo: finish + } + else throw new IllegalArgumentException("Dimension not match or shape not supported."); + } +} diff --git a/src/java/TwoD/definition/Point2D.java b/src/java/TwoD/definition/Point2D.java new file mode 100644 index 0000000..c815946 --- /dev/null +++ b/src/java/TwoD/definition/Point2D.java @@ -0,0 +1,57 @@ +package TwoD.definition; + +import IDefinition.IPoint; +import IDefinition.IShape; + +import java.util.List; + +public class Point2D implements IPoint { + private final double x; + private final double y; + + public Point2D(double x, double y) { + this.x = x; + this.y = y; + } + + public double getX() { + return x; + } + + public double getY() { + return y; + } + + @Override + public List toList() { + return List.of(x,y); + } + + @Override + public double distance(IShape shape) { + if(shape instanceof Point2D point) { + return Math.sqrt(Math.pow(point.getX()-x,2)+Math.pow(point.getY()-y,2)); + } + else throw new IllegalArgumentException("Dimension not match."); + } + + @Override + public boolean equals(Object obj) { + if(obj == this) + return true; + if(obj instanceof Point2D){ + return x == ((Point2D) obj).getX() && y == ((Point2D) obj).getY(); + } + else return false; + } + + @Override + public int hashCode() { + return Double.hashCode(x)+Double.hashCode(y); + } + + @Override + public String toString() { + return String.format("Point2D (%f, %f)",x,y); + } +} diff --git a/src/java/TwoD/definition/Polygon.java b/src/java/TwoD/definition/Polygon.java new file mode 100644 index 0000000..81cc944 --- /dev/null +++ b/src/java/TwoD/definition/Polygon.java @@ -0,0 +1,4 @@ +package TwoD.definition; + +public class Polygon { +} diff --git a/src/java/TwoD/definition/Ray2D.java b/src/java/TwoD/definition/Ray2D.java new file mode 100644 index 0000000..c9558f3 --- /dev/null +++ b/src/java/TwoD/definition/Ray2D.java @@ -0,0 +1,173 @@ +package TwoD.definition; + +import IDefinition.*; + +import javax.naming.OperationNotSupportedException; + +public class Ray2D implements IRay { + + private final Point2D startPoint; + private final Vector2D direction; + + public Ray2D(Point2D startPoint, Vector2D direction) { + if(direction.equals(new Vector2D(0,0))) + throw new IllegalArgumentException("Zero vector cannot be a direction."); + this.startPoint = startPoint; + this.direction = direction; + } + + public Ray2D(Point2D startPoint, Point2D passPoint){ + if(startPoint.equals(passPoint)) + throw new IllegalArgumentException("Try to initialise a ray from two same points."); + this.startPoint = startPoint; + this.direction = new Vector2D(startPoint, passPoint); + } + + @Override + public Point2D getStartPoint() { + return startPoint; + } + + @Override + public boolean parallel(IRay ray) { + return this.direction.parallel(ray.getDirection()); + } + + + public boolean sameDirection(IRay ray) throws OperationNotSupportedException { + return parallel(ray) && this.direction.uniform().equals(ray.getDirection().uniform()); + } + + @Override + public boolean pass(IPoint point) { + if(point instanceof Point2D){ + return point.equals(startPoint)||this.equals(new Ray2D(startPoint,(Point2D) point)); + } + else throw new IllegalArgumentException("Dimension not match."); + } + + @Override + public IShape intersect(IRay ray){ + if(ray instanceof Ray2D){ + boolean intersect = + this.pass(((Ray2D) ray).getStartPoint()) + || ray.pass(this.startPoint) + ||( + this.getDirection().crossProductMod(new Vector2D(this.startPoint, ((Ray2D) ray).getStartPoint()))* + this.getDirection().crossProductMod(((Ray2D) ray).getDirection())<0 + && ((Ray2D)ray).getDirection().crossProductMod(new Vector2D(((Ray2D) ray).startPoint, this.startPoint))* + ((Ray2D)ray).getDirection().crossProductMod(this.direction)<0 + ); + if(intersect) { + boolean sameDirection = false; + try{ + if (this.sameDirection(ray)) sameDirection = true; + } catch (OperationNotSupportedException e) { + e.printStackTrace(); + } + if(this.direction.parallel(((Ray2D) ray).direction) && sameDirection){ + Point2D interP = + this.pass(((Ray2D) ray).startPoint)?((Ray2D) ray).startPoint:this.startPoint; + return new Ray2D(interP, this.direction); + } + else if(this.direction.parallel(((Ray2D) ray).direction) && !sameDirection && + this.startPoint.equals(((Ray2D) ray).startPoint)){ + return this.startPoint; + } + else if(this.direction.parallel(((Ray2D) ray).direction) && !sameDirection && + !this.startPoint.equals(((Ray2D) ray).startPoint)){ + return new Segment2D(this.startPoint, ((Ray2D) ray).startPoint ); + } + else + return new Line2D(direction, startPoint).intersect(new Line2D(((Ray2D) ray).direction, ((Ray2D) ray).getStartPoint())); + } + else return null; + } + else throw new IllegalArgumentException("Dimension not match."); + } + + @Override + public IShape intersect(ISegment segment){ + if(segment instanceof Segment2D){ + boolean intersect = + this.pass(((Segment2D)segment).getP1()) + ||this.pass(((Segment2D)segment).getP2()) + || segment.pass(startPoint) + ||( + this.direction.crossProductMod(new Vector2D(startPoint, ((Segment2D) segment).getP1()))* + this.direction.crossProductMod(new Vector2D(startPoint, ((Segment2D) segment).getP2()))<0 + && ((Segment2D)segment).getDirection().crossProductMod(new Vector2D(((Segment2D) segment).getP1(), startPoint))* + ((Segment2D)segment).getDirection().crossProductMod(direction)<0 + + ); + + if(intersect){ + if(this.pass(((Segment2D)segment).getP1())&&this.pass(((Segment2D) segment).getP2())) { + return segment; + } + else if(this.direction.parallel(segment.getDirection())){ + Point2D interP = + this.pass(((Segment2D)segment).getP1())?((Segment2D)segment).getP1(): ((Segment2D) segment).getP2(); + if(interP.equals(this.startPoint)) { + return interP; + } + else { + return new Segment2D(interP, this.startPoint); + } + } + else { + return new Line2D(direction, startPoint). + intersect(new Line2D(((Segment2D) segment).getP1(), ((Segment2D) segment).getP2())); + } + } + else return null; + } + else throw new IllegalArgumentException("Dimension not match."); + } + + @Override + public IShape intersect(ILine line) { + if(line instanceof Line2D){ + return ((Line2D) line).intersect(this); + } + else throw new IllegalArgumentException("Dimension not match."); + } + + + @Override + public Vector2D getDirection() { + return direction; + } + + @Override + public String toString() { + return "Ray2D from" + startPoint.toString() + "-> Direction:" + direction.toString(); + } + + @Override + public double distance(IShape shape) { + return 0; + } + + @Override + public boolean equals(Object obj){ + if(this==obj) + return true; + if(obj instanceof Ray2D) + return this.startPoint.equals(((Ray2D) obj).startPoint)&& + this.direction.parallel(((Ray2D) obj).direction)&& + this.direction.getX()*((Ray2D) obj).direction.getX()>=0&& + this.direction.getY()*((Ray2D) obj).direction.getY()>=0; + else return false; + } + + @Override + public int hashCode(){ + try { + return this.startPoint.hashCode() + this.direction.uniform().hashCode(); + } catch (OperationNotSupportedException e) { + e.printStackTrace(); + return this.startPoint.hashCode(); + } + } +} diff --git a/src/java/TwoD/definition/Segment2D.java b/src/java/TwoD/definition/Segment2D.java new file mode 100644 index 0000000..1ee5ff3 --- /dev/null +++ b/src/java/TwoD/definition/Segment2D.java @@ -0,0 +1,141 @@ +package TwoD.definition; + +import IDefinition.*; + +public class Segment2D implements ISegment { + + private final Point2D p1; + private final Point2D p2; + private final Vector2D v; + + public Segment2D(Point2D p1, Point2D p2) { + this.p1 = p1; + this.p2 = p2; + this.v = new Vector2D(p1,p2); + } + + + @Override + public IShape intersect(ISegment segment) { + if(segment instanceof Segment2D){ +// boolean intersect = +// segment.pass(p1) +// ||segment.pass(p2) +// ||this.pass(((Segment2D) segment).getP1()) +// ||this.pass(((Segment2D) segment).getP2()) +// ||( +// v.crossProductMod(new Vector2D(p1, ((Segment2D) segment).getP1()))* +// v.crossProductMod(new Vector2D(p1, ((Segment2D) segment).getP2()))<0 +// && ((Segment2D)segment).getDirection().crossProductMod(new Vector2D(((Segment2D) segment).getP1(), p1))* +// ((Segment2D)segment).getDirection().crossProductMod(new Vector2D(((Segment2D) segment).getP1(), p2))<0 +// ); + boolean onEnd = segment.pass(p1) + ||segment.pass(p2) + ||this.pass(((Segment2D) segment).getP1()) + ||this.pass(((Segment2D) segment).getP2()); + boolean intersect = + v.crossProductMod(new Vector2D(p1, ((Segment2D) segment).getP1()))* + v.crossProductMod(new Vector2D(p1, ((Segment2D) segment).getP2()))<0 + && ((Segment2D)segment).getDirection().crossProductMod(new Vector2D(((Segment2D) segment).getP1(), p1))* + ((Segment2D)segment).getDirection().crossProductMod(new Vector2D(((Segment2D) segment).getP1(), p2))<0; + if (intersect) + return new Line2D(p1,p2).intersect(new Line2D(((Segment2D) segment).getP1(), ((Segment2D) segment).getP2())); + else if(onEnd && v.parallel(((Segment2D) segment).v)){ + if(this.pass(((Segment2D) segment).p1)&&this.pass(((Segment2D) segment).p2)){ + return segment; + } + else if (((Segment2D)segment).pass(p1)&&((Segment2D)segment).pass(p2)){ + return this; + } + else{ + Point2D interPoint1 = this.pass(((Segment2D) segment).getP1()) ? + ((Segment2D) segment).getP1() : + ((Segment2D) segment).getP2(); + Point2D interPoint2 = ((Segment2D) segment).pass(p1) ? p1 : p2; + return new Segment2D(interPoint1,interPoint2); + } + + } + else return null; + } + else throw new IllegalArgumentException("Dimension not match."); + } + + @Override + public IShape intersect(ILine line) { + if(line instanceof Line2D){ + return line.intersect(this); + } + else throw new IllegalArgumentException("Dimension not match."); + } + + @Override + public IShape intersect(IRay ray) { + if (ray instanceof Ray2D){ + return ((Ray2D)ray).intersect(this); + } + else throw new IllegalArgumentException("Dimension not match."); + } + + @Override + public Point2D[] getEnds() { + return new Point2D[]{p1,p2}; + } + + @Override + public double getLength() { + return new Vector2D(p1,p2).modular(); + } + + + + @Override + public Vector2D getDirection() { + return v; + } + + @Override + public boolean pass(IPoint point) { + if(point instanceof Point2D){ + return ((Point2D) point).getX() <=Math.max(p1.getX(),p2.getX()) + && ((Point2D) point).getX() >= Math.min(p1.getX(),p2.getX()) + && new Vector2D((Point2D) point,p1).parallel(v); + } + else throw new IllegalArgumentException("Dimension not match."); + } + + public Point2D getP1() { + return p1; + } + + public Point2D getP2() { + return p2; + } + + @Override + public String toString() { + return "Segment2D from " + p1 + " to " + p2; + } + + @Override + public double distance(IShape shape) { + return 0; + } + + @Override + public boolean equals(Object o){ + if(this==o) + return true; + if(o instanceof Segment2D){ + return p1.equals(((Segment2D) o).p1)&&p2.equals(((Segment2D) o).p2)|| + p1.equals(((Segment2D) o).p2)&&p2.equals(((Segment2D) o).p1); + } + else + return false; + } + + @Override + public int hashCode(){ + return p1.hashCode() + p2.hashCode(); + } +} diff --git a/src/java/TwoD/definition/Triangle.java b/src/java/TwoD/definition/Triangle.java new file mode 100644 index 0000000..a4b777c --- /dev/null +++ b/src/java/TwoD/definition/Triangle.java @@ -0,0 +1,4 @@ +package TwoD.definition; + +public class Triangle { +} diff --git a/src/java/TwoD/definition/Vector2D.java b/src/java/TwoD/definition/Vector2D.java new file mode 100644 index 0000000..d30fb0e --- /dev/null +++ b/src/java/TwoD/definition/Vector2D.java @@ -0,0 +1,111 @@ +package TwoD.definition; + +import IDefinition.IVector; +import javax.naming.OperationNotSupportedException; + +public class Vector2D implements IVector { + + private double x; + private double y; + + public Vector2D(double x, double y) { + this.x = x; + this.y = y; + } + + public Vector2D(@org.jetbrains.annotations.NotNull Point2D startPoint, @org.jetbrains.annotations.NotNull Point2D endPoint){ + this.x = endPoint.getX()- startPoint.getX(); + this.y = endPoint.getY() - startPoint.getY(); + } + + public double getX() { + return x; + } + + public void setX(double x) { + this.x = x; + } + + public double getY() { + return y; + } + + public void setY(double y) { + this.y = y; + } + + @Override + public boolean parallel(IVector vector) { + if(!(vector instanceof Vector2D)) + throw new IllegalArgumentException("Dimension not match"); + else + return x* ((Vector2D) vector).getY() == y* ((Vector2D) vector).getX(); + } + + @Override + public double dotProduct(IVector vector) { + if(!(vector instanceof Vector2D)) + throw new IllegalArgumentException("Dimension not match"); + + else + return x* ((Vector2D) vector).getX()+y* ((Vector2D) vector).getY(); + } + + @Override + public Vector2D uniform() throws OperationNotSupportedException { + if(modular()==0) + throw new OperationNotSupportedException("Zero vector."); + else{ + return this.multiply(1/modular()); + } + } + + @Override + public double modular() { + return Math.sqrt(x*x+y*y); + } + + @Override + public Vector2D add(IVector vector) { + if(vector instanceof Vector2D){ + return new Vector2D(x + ((Vector2D) vector).x, y + ((Vector2D) vector).y); + } + else throw new IllegalArgumentException("Dimension not match."); + } + + @Override + public Vector2D multiply(double a) { + return new Vector2D(x*a, y*a); + } + + @Override + public boolean equals(Object obj) { + if(obj == this) + return true; + if(obj instanceof Vector2D) + return x == ((Vector2D) obj).getX() && y == ((Vector2D) obj).getY(); + else return false; + } + + @Override + public int hashCode() { + return Double.hashCode(x)+Double.hashCode(y); + } + + @Override + public String toString() { + return String.format("Vector2D (%f, %f)",x,y); + } + + public Vector2D computePerpendicular(){ + return new Vector2D(getY(), -1*getX()); + } + + public double crossProductMod(Vector2D v){ + return this.x*v.y - this.y*v.x; + } + + public boolean isZeroVector(){ + return this.modular()==0; + } +} diff --git a/src/test/java/BasicElementInitialisationTest.java b/src/test/java/BasicElementInitialisationTest.java new file mode 100644 index 0000000..b2424af --- /dev/null +++ b/src/test/java/BasicElementInitialisationTest.java @@ -0,0 +1,98 @@ +import TwoD.definition.*; +import com.google.common.util.concurrent.RateLimiter; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import javax.sound.sampled.Line; + +import static com.google.common.truth.Truth.assertThat; +@RunWith(JUnit4.class) +public class BasicElementInitialisationTest { + @Test + public void Point2DCreate(){ + //arrange + Point2D p = new Point2D(0,0); + //act + String s = p.toString(); + //assert + assertThat(s).startsWith("Point2D"); + assertThat(p.getX()).isEqualTo(0); + assertThat(p.getY()).isEqualTo(0); + assertThat(p.toList()).containsExactly(0.0,0.0); + } + + @Test + public void Ray2DCreateStartAndDirection(){ + //arrange + Point2D start = new Point2D(0,0); + Vector2D v = new Vector2D(1,0); + //act + Ray2D r = new Ray2D(start,v); + //assert + assertThat(r.toString()).startsWith("Ray2D"); + System.out.println(r); + assertThat(r.getDirection()).isEqualTo(v); + assertThat(r.getStartPoint()).isEqualTo(start); + } + + @Test + public void Ray2DCreateFromTwoPoints(){ + //arrange + Point2D start = new Point2D(0,0); + Point2D pass = new Point2D(1,0); + //act + Ray2D r = new Ray2D(start,pass); + //assert + assertThat(r.toString()).startsWith("Ray2D"); + System.out.println(r); + assertThat(r.getDirection().parallel(new Vector2D(1,0))).isTrue(); + assertThat(r.getStartPoint()).isEqualTo(start); + } + + @Test + public void SegmentCreate(){ + //arrange + Point2D p1 = new Point2D(0,0); + Point2D p2 = new Point2D(0,1); + //act + Segment2D seg = new Segment2D(p1,p2); + //assert + assertThat(seg.toString()).startsWith("Segment2D"); + System.out.println(seg); + assertThat(seg.getP1()).isEqualTo(p1); + assertThat(seg.getP2()).isEqualTo(p2); + assertThat(seg.getDirection()).isEqualTo(new Vector2D(p1,p2)); + } + + @Test + public void LineCreateFromTwoPoints(){ + //arrange + Point2D p1 = new Point2D(0,0); + Point2D p2 = new Point2D(0,1); + //act + Line2D line = new Line2D(p1,p2); + //assert + assertThat(line.toString()).startsWith("Line2D"); + System.out.println(line); + assertThat(line.getDirection().parallel(new Vector2D(p1,p2))).isTrue(); + assertThat(line.pass(line.getOnePassPoint())).isTrue(); + assertThat(line.pass(p1)).isTrue(); + assertThat(line.pass(p2)).isTrue(); + } + + @Test + public void LineCreateFromDirectionAndPoint(){ + //arrange + Point2D p = new Point2D(0,0); + Vector2D v = new Vector2D(0,1); + //act + Line2D line = new Line2D(v,p); + //assert + assertThat(line.toString()).startsWith("Line2D"); + System.out.println(line); + assertThat(line.getDirection().parallel(v)).isTrue(); + assertThat(line.pass(p)).isTrue(); + assertThat(line.pass(line.getOnePassPoint())).isTrue(); + } +} diff --git a/src/test/java/LineLineIntersectionTest.java b/src/test/java/LineLineIntersectionTest.java new file mode 100644 index 0000000..7e8a2c4 --- /dev/null +++ b/src/test/java/LineLineIntersectionTest.java @@ -0,0 +1,89 @@ +import IDefinition.IShape; +import TwoD.definition.Line2D; +import TwoD.definition.Point2D; +import TwoD.definition.Vector2D; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import static com.google.common.truth.Truth.assertThat; + +@RunWith(JUnit4.class) +public class LineLineIntersectionTest { + @Test + public void SameLineIntersection(){ + //arrange + Line2D l1 = new Line2D(new Vector2D(1,0), new Point2D(0,0)); + Line2D l2 = new Line2D(new Vector2D(1,0), new Point2D(1,0)); + //act + IShape result = l1.intersect(l2); + //assert + assertThat(result).isEqualTo(l1); + } + + @Test + public void parallelLineIntersect(){ + //arrange + Line2D l1 = new Line2D(new Vector2D(1,0), new Point2D(0,0)); + Line2D l2 = new Line2D(new Vector2D(1,0), new Point2D(1,1)); + //act + IShape result = l1.intersect(l2); + //assert + assertThat(result).isNull(); + } + + @Test + public void normalIntersection(){ + //arrange + Line2D l1 = new Line2D(new Vector2D(1,1), new Point2D(0,0)); + Line2D l2 = new Line2D(new Vector2D(1,-1), new Point2D(0,2)); + //act + IShape result = l1.intersect(l2); + //assert + assertThat(result).isEqualTo(new Point2D(1,1)); + } + + @Test + public void normalIntersection2(){ + //arrange + Line2D l1 = new Line2D(new Vector2D(1,1), new Point2D(1,1)); + Line2D l2 = new Line2D(new Vector2D(1,-1), new Point2D(0,2)); + //act + IShape result = l1.intersect(l2); + //assert + assertThat(result).isEqualTo(new Point2D(1,1)); + } + + @Test + public void normalIntersection3(){ + //arrange + Line2D l1 = new Line2D(new Vector2D(1,2), new Point2D(1,0)); + Line2D l2 = new Line2D(new Vector2D(2,1), new Point2D(0,1)); + //act + IShape result = l1.intersect(l2); + //assert + assertThat(result).isEqualTo(new Point2D(2,2)); + } + + @Test + public void normalIntersection4(){ + //arrange + Line2D l1 = new Line2D(new Vector2D(1,0), new Point2D(1,0)); + Line2D l2 = new Line2D(new Vector2D(0,1), new Point2D(0,1)); + //act + IShape result = l1.intersect(l2); + //assert + assertThat(result).isEqualTo(new Point2D(0,0)); + } + + @Test + public void normalIntersection5(){ + //arrange + Line2D l1 = new Line2D(new Vector2D(1,1), new Point2D(1,1)); + Line2D l2 = new Line2D(new Vector2D(0,1), new Point2D(5,0)); + //act + IShape result = l1.intersect(l2); + //assert + assertThat(result).isEqualTo(new Point2D(5,5)); + } +} diff --git a/src/test/java/RaysIntersection.java b/src/test/java/RaysIntersection.java new file mode 100644 index 0000000..3ad11b5 --- /dev/null +++ b/src/test/java/RaysIntersection.java @@ -0,0 +1,91 @@ +import IDefinition.ISegment; +import IDefinition.IShape; +import TwoD.definition.Point2D; +import TwoD.definition.Ray2D; + +import TwoD.definition.Segment2D; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import static com.google.common.truth.Truth.assertThat; + +@RunWith(JUnit4.class) +public class RaysIntersection { + @Test + public void SameRayIntersect(){ + //arrange + Ray2D r1 = new Ray2D(new Point2D(0,0), new Point2D(1,0)); + Ray2D r2 = new Ray2D(new Point2D(0,0), new Point2D(2,0)); + //act + IShape result = r1.intersect(r2); + //assert + assertThat(result).isEqualTo(r1); + } + + @Test + public void parallelNotSameDirectionReturnStartPoint(){ + //arrange + Ray2D r1 = new Ray2D(new Point2D(0,0), new Point2D(1,0)); + Ray2D r2 = new Ray2D(new Point2D(0,0), new Point2D(-2,0)); + //act + IShape result = r1.intersect(r2); + //assert + assertThat(result).isEqualTo(new Point2D(0,0)); + } + + @Test + public void parallelNotSameDirectionReturnSegment(){ + //arrange + Ray2D r1 = new Ray2D(new Point2D(0,0), new Point2D(1,0)); + Ray2D r2 = new Ray2D(new Point2D(1,0), new Point2D(-2,0)); + //act + IShape result = r1.intersect(r2); + //assert + assertThat(result).isEqualTo(new Segment2D(new Point2D(0,0), new Point2D(1,0))); + } + + @Test + public void parallelNotIntersect(){ + //arrange + Ray2D r1 = new Ray2D(new Point2D(0,0), new Point2D(1,0)); + Ray2D r2 = new Ray2D(new Point2D(0,1), new Point2D(-2,1)); + //act + IShape result = r1.intersect(r2); + //assert + assertThat(result).isNull(); + } + + @Test + public void NotParallelNotIntersect(){ + //arrange + Ray2D r1 = new Ray2D(new Point2D(0,0), new Point2D(1,-1)); + Ray2D r2 = new Ray2D(new Point2D(0,1), new Point2D(1,1)); + //act + IShape result = r1.intersect(r2); + //assert + assertThat(result).isNull(); + } + + @Test + public void NormalIntersect1(){ + //arrange + Ray2D r1 = new Ray2D(new Point2D(0,0), new Point2D(2,2)); + Ray2D r2 = new Ray2D(new Point2D(0,2), new Point2D(2,0)); + //act + IShape result = r1.intersect(r2); + //assert + assertThat(result).isEqualTo(new Point2D(1,1)); + } + + @Test + public void NormalIntersect2(){ + //arrange + Ray2D r1 = new Ray2D(new Point2D(0,0), new Point2D(2,2)); + Ray2D r2 = new Ray2D(new Point2D(0,0), new Point2D(2,0)); + //act + IShape result = r1.intersect(r2); + //assert + assertThat(result).isEqualTo(new Point2D(0,0)); + } +} diff --git a/src/test/java/SegmentRayIntersectionTest.java b/src/test/java/SegmentRayIntersectionTest.java new file mode 100644 index 0000000..de37f0d --- /dev/null +++ b/src/test/java/SegmentRayIntersectionTest.java @@ -0,0 +1,92 @@ +import IDefinition.IShape; +import TwoD.definition.Point2D; +import TwoD.definition.Ray2D; +import TwoD.definition.Segment2D; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import static com.google.common.truth.Truth.assertThat; +@RunWith(JUnit4.class) +public class SegmentRayIntersectionTest { + @Test + public void parallelNotIntersect(){ + //arrange + Ray2D ray = new Ray2D(new Point2D(0,0), new Point2D(1,0)); + Segment2D seg = new Segment2D(new Point2D(0,1), new Point2D(1,1)); + //act + IShape result1 = ray.intersect(seg); + IShape result2 = seg.intersect(ray); + + //assert + assertThat(result1).isNull(); + assertThat(result2).isNull(); + } + + @Test + public void NotParallelNotIntersect(){ + //arrange + Ray2D ray = new Ray2D(new Point2D(0,0), new Point2D(1,0)); + Segment2D seg = new Segment2D(new Point2D(0,1), new Point2D(1,2)); + //act + IShape result1 = ray.intersect(seg); + IShape result2 = seg.intersect(ray); + //assert + assertThat(result1).isNull(); + assertThat(result2).isNull(); + } + + @Test + public void intersectOnEnd(){ + + Ray2D ray = new Ray2D(new Point2D(0,0), new Point2D(1,0)); + Segment2D seg = new Segment2D(new Point2D(0,0), new Point2D(1,2)); + //act + IShape result1 = ray.intersect(seg); + IShape result2 = seg.intersect(ray); + //assert + assertThat(result1).isEqualTo(new Point2D(0,0)); + assertThat(result2).isEqualTo(new Point2D(0,0)); + } + + @Test + public void intersectNormal(){ + //arrange + Ray2D ray = new Ray2D(new Point2D(0,0), new Point2D(1,1)); + Segment2D seg = new Segment2D(new Point2D(0,0.5), new Point2D(2,1.5)); + //act + IShape result1 = ray.intersect(seg); + IShape result2 = seg.intersect(ray); + //assert + assertThat(result1).isEqualTo(new Point2D(1,1)); + assertThat(result2).isEqualTo(new Point2D(1,1)); + } + + @Test + public void rayContainSegment(){ + //arrange + Ray2D ray = new Ray2D(new Point2D(0,0), new Point2D(1,0)); + Segment2D seg = new Segment2D(new Point2D(0,0), new Point2D(1,0)); + //act + IShape result1 = ray.intersect(seg); + IShape result2 = seg.intersect(ray); + //assert + assertThat(result1).isEqualTo(new Segment2D(new Point2D(0,0),new Point2D(1,0))); + assertThat(result2).isEqualTo(new Segment2D(new Point2D(0,0),new Point2D(1,0))); + } + + @Test + public void rayContainPartOfTheSegment(){ + //arrange + Ray2D ray = new Ray2D(new Point2D(0,0), new Point2D(1,0)); + Segment2D seg = new Segment2D(new Point2D(-1,0), new Point2D(1,0)); + //act + IShape result1 = ray.intersect(seg); + IShape result2 = seg.intersect(ray); + //assert + assertThat(result1).isEqualTo(new Segment2D(new Point2D(0,0),new Point2D(1,0))); + assertThat(result2).isEqualTo(new Segment2D(new Point2D(0,0),new Point2D(1,0))); + } + +} diff --git a/src/test/java/SegmentsIntersectTest.java b/src/test/java/SegmentsIntersectTest.java new file mode 100644 index 0000000..8d0b7a2 --- /dev/null +++ b/src/test/java/SegmentsIntersectTest.java @@ -0,0 +1,90 @@ +import IDefinition.IShape; +import TwoD.definition.Point2D; +import TwoD.definition.Segment2D; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import static com.google.common.truth.Truth.assertThat; + +@RunWith(JUnit4.class) +public class SegmentsIntersectTest { + @Test + public void SegmentNotIntersect() { + //arrange + Segment2D s1 = new Segment2D(new Point2D(0, 0), new Point2D(1, 0)); + Segment2D s2 = new Segment2D(new Point2D(1, 1), new Point2D(2, 1)); + //act + IShape result = s1.intersect(s2); + //assert + assertThat(result).isNull(); + } + + @Test + public void SegmentIntersectOnEnd() { + //arrange + Segment2D s1 = new Segment2D(new Point2D(0, 0), new Point2D(2, 0)); + Segment2D s2 = new Segment2D(new Point2D(1, 0), new Point2D(1, 1)); + //act + IShape result = s1.intersect(s2); + //assert + assertThat(result).isEqualTo(new Point2D(1, 0)); + } + + @Test + public void SegmentIntersectOnTheOtherEnd() { + //arrange + Segment2D s2 = new Segment2D(new Point2D(0, 0), new Point2D(2, 0)); + Segment2D s1 = new Segment2D(new Point2D(1, 0), new Point2D(1, 1)); + //act + IShape result = s1.intersect(s2); + //assert + assertThat(result).isEqualTo(new Point2D(1, 0)); + } + + @Test + public void SegmentIntersectNormal1() { + //arrange + Segment2D s2 = new Segment2D(new Point2D(0, 0), new Point2D(2, 0)); + Segment2D s1 = new Segment2D(new Point2D(1, -1), new Point2D(1, 1)); + //act + IShape result = s1.intersect(s2); + //assert + assertThat(result).isEqualTo(new Point2D(1, 0)); + } + + @Test + public void SegmentIntersectNormal2() { + //arrange + Segment2D s2 = new Segment2D(new Point2D(0, 0), new Point2D(2, 0)); + Segment2D s1 = new Segment2D(new Point2D(0, -2), new Point2D(2, 2)); + //act + IShape result = s1.intersect(s2); + //assert + assertThat(result).isEqualTo(new Point2D(1, 0)); + } + + @Test + public void SegmentContainIntersect() { + //arrange + Segment2D s2 = new Segment2D(new Point2D(0, 0), new Point2D(2, 0)); + Segment2D s1 = new Segment2D(new Point2D(0, 0), new Point2D(1, 0)); + //act + IShape result = s1.intersect(s2); + //assert + assertThat(result).isEqualTo(new Segment2D(new Point2D(0, 0), new Point2D(1, 0))); + } + + @Test + public void SegmentOnTheSameLineIntersect() { + //arrange + Segment2D s2 = new Segment2D(new Point2D(-1, 0), new Point2D(2, 0)); + Segment2D s1 = new Segment2D(new Point2D(0, 0), new Point2D(1, 0)); + //act + IShape result = s1.intersect(s2); + //assert + assertThat(result).isEqualTo(new Segment2D(new Point2D(0, 0), new Point2D(1, 0))); + + } +}