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)));
+
+ }
+}