test_class.declarator: pentagon
test_class.modifier: private static
test_class.original_string: private static Polygon pentagon;
test_class.type: Polygon
test_class.var_name: pentagon
test_class.declarator: concavePentagon
test_class.modifier: private static
test_class.original_string: private static Polygon concavePentagon;
test_class.type: Polygon
test_class.var_name: concavePentagon
test_class.declarator: complexPentagon
test_class.modifier: private static
test_class.original_string: private static Polygon complexPentagon;
test_class.type: Polygon
test_class.var_name: complexPentagon
test_class.file: singa-mathematics/src/test/java/bio/singa/mathematics/geometry/faces/PolygonsTest.java
test_class.identifier: PolygonsTest
test_case.body: @Test
      void getTouchingLineSegmentsTrivial() {
  
          Polygon first = new Rectangle(new Vector2D(100, 100), new Vector2D(200, 200));
          Polygon second = new Rectangle(new Vector2D(200, 100), new Vector2D(300, 200));
  
          Map<Pair<LineSegment>, LineSegment> touchingLineSegments = Polygons.getTouchingLineSegments(first, second);
          Map.Entry<Pair<LineSegment>, LineSegment> entry = touchingLineSegments.entrySet().iterator().next();
  
          assertTrue(new SimpleLineSegment(new Vector2D(200.0, 100.0), new Vector2D(200.0, 200.0)).isCongruentTo(entry.getKey().getFirst()));
          assertTrue(new SimpleLineSegment(new Vector2D(200.0, 200.0), new Vector2D(200.0, 100.0)).isCongruentTo(entry.getKey().getSecond()));
          assertTrue(new SimpleLineSegment(new Vector2D(200.0, 200.0), new Vector2D(200.0, 100.0)).isCongruentTo(entry.getValue()));
      }
test_case.class_method_signature: PolygonsTest.getTouchingLineSegmentsTrivial()
test_case.full_signature: @Test void getTouchingLineSegmentsTrivial()
test_case.identifier: getTouchingLineSegmentsTrivial
test_case.invocations: getTouchingLineSegments next iterator entrySet assertTrue isCongruentTo getFirst getKey assertTrue isCongruentTo getSecond getKey assertTrue isCongruentTo getValue
test_case.modifiers: @Test
test_case.parameters: ()
test_case.return: void
test_case.signature: void getTouchingLineSegmentsTrivial()
focal_class.declarator: OUTSIDE = -1
focal_class.modifier: public static final
focal_class.original_string: public static final int OUTSIDE = -1;
focal_class.type: int
focal_class.var_name: OUTSIDE
focal_class.declarator: ON_LINE = 0
focal_class.modifier: public static final
focal_class.original_string: public static final int ON_LINE = 0;
focal_class.type: int
focal_class.var_name: ON_LINE
focal_class.declarator: INSIDE = 1
focal_class.modifier: public static final
focal_class.original_string: public static final int INSIDE = 1;
focal_class.type: int
focal_class.var_name: INSIDE
focal_class.file: singa-mathematics/src/main/java/bio/singa/mathematics/geometry/faces/Polygons.java
focal_class.identifier: Polygons
focal_class.class_method_signature: Polygons.containsVector(Polygon polygon, Vector2D vector)
focal_class.full_signature: public static boolean containsVector(Polygon polygon, Vector2D vector)
focal_class.identifier: containsVector
focal_class.modifiers: public static
focal_class.parameters: (Polygon polygon, Vector2D vector)
focal_class.return: boolean
focal_class.signature: boolean containsVector(Polygon polygon, Vector2D vector)
focal_class.class_method_signature: Polygons.getTouchingLineSegments(Polygon first, Polygon second)
focal_class.full_signature: public static Map<Pair<LineSegment>, LineSegment> getTouchingLineSegments(Polygon first, Polygon second)
focal_class.identifier: getTouchingLineSegments
focal_class.modifiers: public static
focal_class.parameters: (Polygon first, Polygon second)
focal_class.return: Map<Pair<LineSegment>, LineSegment>
focal_class.signature: Map<Pair<LineSegment>, LineSegment> getTouchingLineSegments(Polygon first, Polygon second)
focal_class.class_method_signature: Polygons.unitVectorsAreParallel(Vector2D firstUnitVector, Vector2D secondUnitVector)
focal_class.full_signature: private static boolean unitVectorsAreParallel(Vector2D firstUnitVector, Vector2D secondUnitVector)
focal_class.identifier: unitVectorsAreParallel
focal_class.modifiers: private static
focal_class.parameters: (Vector2D firstUnitVector, Vector2D secondUnitVector)
focal_class.return: boolean
focal_class.signature: boolean unitVectorsAreParallel(Vector2D firstUnitVector, Vector2D secondUnitVector)
focal_method.body: public static Map<Pair<LineSegment>, LineSegment> getTouchingLineSegments(Polygon first, Polygon second) {
  
          // groups line segments that are pairwise parallel
          List<List<Pair<LineSegment>>> allParallelSegments = new ArrayList<>();
          List<Pair<LineSegment>> touchingLineSegments = new ArrayList<>();
          Map<Pair<LineSegment>, LineSegment> resultMap = new HashMap<>();
  
          // determine which lines are parallel
          for (LineSegment firstLineSegment : first.getEdges()) {
              for (LineSegment secondLineSegment : second.getEdges()) {
                  // trivial case: if both lines are identical definitely touch
                  if (firstLineSegment.isCongruentTo(secondLineSegment)) {
                      resultMap.put(new Pair<>(firstLineSegment, secondLineSegment), firstLineSegment);
                      break;
                  }
                  // two line segments are parallel if their unit vectors are equal or opposite
                  Vector2D firstUnitVector = firstLineSegment.getUnitVector();
                  Vector2D secondUnitVector = secondLineSegment.getUnitVector();
                  if (unitVectorsAreParallel(firstUnitVector, secondUnitVector)) {
                      // sort them to a list where all line segments are parallel
                      boolean sorted = false;
                      for (List<Pair<LineSegment>> parallelSegmentGroup : allParallelSegments) {
                          Vector2D representativeUnitVector = parallelSegmentGroup.iterator().next().getFirst().getUnitVector();
                          if (unitVectorsAreParallel(firstUnitVector, representativeUnitVector)) {
                              parallelSegmentGroup.add(new Pair<>(firstLineSegment, secondLineSegment));
                              sorted = true;
                              break;
                          }
                      }
                      // create new group if it could not be sorted into existing ones
                      if (!sorted) {
                          List<Pair<LineSegment>> parallelSegmentGroup = new ArrayList<>();
                          parallelSegmentGroup.add(new Pair<>(firstLineSegment, secondLineSegment));
                          allParallelSegments.add(parallelSegmentGroup);
                      }
                  }
              }
          }
  
          // determine which sides touch
          for (List<Pair<LineSegment>> parallelSegmentGroup : allParallelSegments) {
              for (int firstIterator = 0; firstIterator < parallelSegmentGroup.size(); firstIterator++) {
                  // creates unit vectors from first segment
                  LineSegment firstSegment = parallelSegmentGroup.get(firstIterator).getFirst();
                  Vector2D referenceUnitVector = firstSegment.getUnitVector();
                  for (int secondIterator = firstIterator; secondIterator < parallelSegmentGroup.size(); secondIterator++) {
                      // when connecting another point to the start of they first segment they run parallel if their unit vectors are equal or opposite
                      LineSegment secondSegment = parallelSegmentGroup.get(secondIterator).getSecond();
                      Vector2D startingPoint = firstSegment.getStartingPoint();
                      Vector2D endingPoint = secondSegment.getEndingPoint();
                      if (startingPoint.equals(endingPoint)) {
                          endingPoint = secondSegment.getStartingPoint();
                      }
                      Vector2D candidateUnitVector = new SimpleLineSegment(startingPoint, endingPoint).getUnitVector();
                      if (unitVectorsAreParallel(referenceUnitVector, candidateUnitVector)) {
                          Pair<LineSegment> segmentPair = new Pair<>(firstSegment, secondSegment);
                          touchingLineSegments.add(segmentPair);
                      }
                  }
              }
          }
  
          // determine resulting touching line segments
          for (Pair<LineSegment> touchingSegmentPair : touchingLineSegments) {
              LineSegment firstSegment = touchingSegmentPair.getFirst();
              LineSegment secondSegment = touchingSegmentPair.getSecond();
              // possible containment relations
              boolean secondStartOnFirst = firstSegment.isOnLine(secondSegment.getStartingPoint());
              boolean secondEndOnFirst = firstSegment.isOnLine(secondSegment.getEndingPoint());
              boolean firstStartOnSecond = secondSegment.isOnLine(firstSegment.getStartingPoint());
              boolean firstEndOnSecond = secondSegment.isOnLine(firstSegment.getEndingPoint());
              // determine what is the case
              if (secondStartOnFirst && secondEndOnFirst) {
                  // case 1: second is contained in first
                  resultMap.put(touchingSegmentPair, secondSegment);
              } else if (firstStartOnSecond && firstEndOnSecond) {
                  // case 2: first is contained in second
                  resultMap.put(touchingSegmentPair, firstSegment);
              } else {
                  // case 3: neither is contained in the other they only overlap
                  if (secondStartOnFirst && firstStartOnSecond) {
                      if (!secondSegment.getStartingPoint().equals(firstSegment.getStartingPoint())) {
                          resultMap.put(touchingSegmentPair, new SimpleLineSegment(secondSegment.getStartingPoint(), firstSegment.getStartingPoint()));
                      }
                  } else if (secondStartOnFirst && firstEndOnSecond) {
                      if (!secondSegment.getStartingPoint().equals(firstSegment.getEndingPoint())) {
                          resultMap.put(touchingSegmentPair, new SimpleLineSegment(secondSegment.getStartingPoint(), firstSegment.getEndingPoint()));
                      }
                  } else if (secondEndOnFirst && firstStartOnSecond) {
                      if (!secondSegment.getEndingPoint().equals(firstSegment.getStartingPoint())) {
                          resultMap.put(touchingSegmentPair, new SimpleLineSegment(secondSegment.getEndingPoint(), firstSegment.getStartingPoint()));
                      }
                  } else if (secondEndOnFirst && firstEndOnSecond) {
                      if (!secondSegment.getEndingPoint().equals(firstSegment.getEndingPoint())) {
                          resultMap.put(touchingSegmentPair, new SimpleLineSegment(secondSegment.getEndingPoint(), firstSegment.getEndingPoint()));
                      }
                  }
              }
  
          }
  
          return resultMap;
      }
focal_method.class_method_signature: Polygons.getTouchingLineSegments(Polygon first, Polygon second)
focal_method.full_signature: public static Map<Pair<LineSegment>, LineSegment> getTouchingLineSegments(Polygon first, Polygon second)
focal_method.identifier: getTouchingLineSegments
focal_method.invocations: getEdges getEdges isCongruentTo put getUnitVector getUnitVector unitVectorsAreParallel getUnitVector getFirst next iterator unitVectorsAreParallel add add add size getFirst get getUnitVector size getSecond get getStartingPoint getEndingPoint equals getStartingPoint getUnitVector unitVectorsAreParallel add getFirst getSecond isOnLine getStartingPoint isOnLine getEndingPoint isOnLine getStartingPoint isOnLine getEndingPoint put put equals getStartingPoint getStartingPoint put getStartingPoint getStartingPoint equals getStartingPoint getEndingPoint put getStartingPoint getEndingPoint equals getEndingPoint getStartingPoint put getEndingPoint getStartingPoint equals getEndingPoint getEndingPoint put getEndingPoint getEndingPoint
focal_method.modifiers: public static
focal_method.parameters: (Polygon first, Polygon second)
focal_method.return: Map<Pair<LineSegment>, LineSegment>
focal_method.signature: Map<Pair<LineSegment>, LineSegment> getTouchingLineSegments(Polygon first, Polygon second)