@Test public void testIntersectionArea() { assertThat(penaltyArea.intersectionArea( Vector2.fromXY(goalX + depth / 2, -length / 2), Vector2.fromXY(goalX + depth / 2, length / 2))) .isCloseTo(depth / 2 * length * 1e-6, within(1e-6)); assertThat(penaltyArea.intersectionArea( Vector2.fromXY(goalX + depth * 0.5, -length / 2), Vector2.fromXY(goalX + depth * 0.8, length / 2))) .isCloseTo(((depth * 0.2) * length + (depth * 0.3) * length * 0.5) * 1e-6, within(1e-6)); assertThat(penaltyArea.intersectionArea( Vector2.fromXY(goalX + depth * 0.5, -length / 2), Vector2.fromXY(goalX + depth, 0))) .isCloseTo((depth * 0.5) * (length * 0.5) * 0.5 * 1e-6, within(1e-6)); }
@Override public double intersectionArea(final IVector2 from, final IVector2 to) { if (isBehindPenaltyArea(from) || isBehindPenaltyArea(to)) { return depth * length * 1e-6; } ILineSegment line = Lines.segmentFromPoints( rectangle.nearestPointOutside(from), rectangle.nearestPointOutside(to)); List<IVector2> intersections = rectangle.lineIntersections(line); if (intersections.size() != 2) { return 0; } IVector2 p1 = intersections.get(0); IVector2 p2 = intersections.get(1); if (SumatraMath.isEqual(p1.x(), goalCenterX) || SumatraMath.isEqual(p2.x(), goalCenterX)) { return depth * length * 1e-6; } double frontX = goalCenterX - Math.signum(goalCenterX) * depth; double dp1 = Math.abs(frontX - p1.x()); double dp2 = Math.abs(frontX - p2.x()); double dMin = Math.min(dp1, dp2); double a = Math.max(dp1, dp2) - dMin; double l = Math.abs(p1.y() - p2.y()); return (l * dMin + l * a * 0.5) * 1e-6; }
PenaltyArea implements IPenaltyArea { @Override public double intersectionArea(final IVector2 from, final IVector2 to) { if (isBehindPenaltyArea(from) || isBehindPenaltyArea(to)) { return depth * length * 1e-6; } ILineSegment line = Lines.segmentFromPoints( rectangle.nearestPointOutside(from), rectangle.nearestPointOutside(to)); List<IVector2> intersections = rectangle.lineIntersections(line); if (intersections.size() != 2) { return 0; } IVector2 p1 = intersections.get(0); IVector2 p2 = intersections.get(1); if (SumatraMath.isEqual(p1.x(), goalCenterX) || SumatraMath.isEqual(p2.x(), goalCenterX)) { return depth * length * 1e-6; } double frontX = goalCenterX - Math.signum(goalCenterX) * depth; double dp1 = Math.abs(frontX - p1.x()); double dp2 = Math.abs(frontX - p2.x()); double dMin = Math.min(dp1, dp2); double a = Math.max(dp1, dp2) - dMin; double l = Math.abs(p1.y() - p2.y()); return (l * dMin + l * a * 0.5) * 1e-6; } }
PenaltyArea implements IPenaltyArea { @Override public double intersectionArea(final IVector2 from, final IVector2 to) { if (isBehindPenaltyArea(from) || isBehindPenaltyArea(to)) { return depth * length * 1e-6; } ILineSegment line = Lines.segmentFromPoints( rectangle.nearestPointOutside(from), rectangle.nearestPointOutside(to)); List<IVector2> intersections = rectangle.lineIntersections(line); if (intersections.size() != 2) { return 0; } IVector2 p1 = intersections.get(0); IVector2 p2 = intersections.get(1); if (SumatraMath.isEqual(p1.x(), goalCenterX) || SumatraMath.isEqual(p2.x(), goalCenterX)) { return depth * length * 1e-6; } double frontX = goalCenterX - Math.signum(goalCenterX) * depth; double dp1 = Math.abs(frontX - p1.x()); double dp2 = Math.abs(frontX - p2.x()); double dMin = Math.min(dp1, dp2); double a = Math.max(dp1, dp2) - dMin; double l = Math.abs(p1.y() - p2.y()); return (l * dMin + l * a * 0.5) * 1e-6; } PenaltyArea(final IVector2 goalCenter, final double depth, final double length); }
PenaltyArea implements IPenaltyArea { @Override public double intersectionArea(final IVector2 from, final IVector2 to) { if (isBehindPenaltyArea(from) || isBehindPenaltyArea(to)) { return depth * length * 1e-6; } ILineSegment line = Lines.segmentFromPoints( rectangle.nearestPointOutside(from), rectangle.nearestPointOutside(to)); List<IVector2> intersections = rectangle.lineIntersections(line); if (intersections.size() != 2) { return 0; } IVector2 p1 = intersections.get(0); IVector2 p2 = intersections.get(1); if (SumatraMath.isEqual(p1.x(), goalCenterX) || SumatraMath.isEqual(p2.x(), goalCenterX)) { return depth * length * 1e-6; } double frontX = goalCenterX - Math.signum(goalCenterX) * depth; double dp1 = Math.abs(frontX - p1.x()); double dp2 = Math.abs(frontX - p2.x()); double dMin = Math.min(dp1, dp2); double a = Math.max(dp1, dp2) - dMin; double l = Math.abs(p1.y() - p2.y()); return (l * dMin + l * a * 0.5) * 1e-6; } PenaltyArea(final IVector2 goalCenter, final double depth, final double length); @Override IPenaltyArea withMargin(final double margin); @Override List<IVector2> lineIntersections(final edu.tigers.sumatra.math.line.v2.ILine line); @Override List<IVector2> lineIntersections(final ILineSegment line); @Override List<IVector2> lineIntersections(final IHalfLine line); @Override List<IVector2> lineIntersections(final ILine line); @Override @SuppressWarnings("squid:S1244") // equality check intended IVector2 projectPointOnToPenaltyAreaBorder(final IVector2 point); @Override boolean isPointInShape(final IVector2 point); @Override boolean isPointInShape(final IVector2 point, final double margin); @Override boolean isPointInShapeOrBehind(final IVector2 point); @Override IVector2 nearestPointInside(final IVector2 point); @Override IVector2 nearestPointOutside(final IVector2 point); @Override boolean isIntersectingWithLine(final ILine line); @Override boolean isBehindPenaltyArea(final IVector2 point); @Override IVector2 getGoalCenter(); @Override Rectangle getRectangle(); @Override IVector2 getNegCorner(); @Override IVector2 getPosCorner(); @Override List<IDrawableShape> getDrawableShapes(); @Override double distanceTo(final IVector2 point); @Override double distanceToNearestPointOutside(final IVector2 pos); @Override double intersectionArea(final IVector2 from, final IVector2 to); }
PenaltyArea implements IPenaltyArea { @Override public double intersectionArea(final IVector2 from, final IVector2 to) { if (isBehindPenaltyArea(from) || isBehindPenaltyArea(to)) { return depth * length * 1e-6; } ILineSegment line = Lines.segmentFromPoints( rectangle.nearestPointOutside(from), rectangle.nearestPointOutside(to)); List<IVector2> intersections = rectangle.lineIntersections(line); if (intersections.size() != 2) { return 0; } IVector2 p1 = intersections.get(0); IVector2 p2 = intersections.get(1); if (SumatraMath.isEqual(p1.x(), goalCenterX) || SumatraMath.isEqual(p2.x(), goalCenterX)) { return depth * length * 1e-6; } double frontX = goalCenterX - Math.signum(goalCenterX) * depth; double dp1 = Math.abs(frontX - p1.x()); double dp2 = Math.abs(frontX - p2.x()); double dMin = Math.min(dp1, dp2); double a = Math.max(dp1, dp2) - dMin; double l = Math.abs(p1.y() - p2.y()); return (l * dMin + l * a * 0.5) * 1e-6; } PenaltyArea(final IVector2 goalCenter, final double depth, final double length); @Override IPenaltyArea withMargin(final double margin); @Override List<IVector2> lineIntersections(final edu.tigers.sumatra.math.line.v2.ILine line); @Override List<IVector2> lineIntersections(final ILineSegment line); @Override List<IVector2> lineIntersections(final IHalfLine line); @Override List<IVector2> lineIntersections(final ILine line); @Override @SuppressWarnings("squid:S1244") // equality check intended IVector2 projectPointOnToPenaltyAreaBorder(final IVector2 point); @Override boolean isPointInShape(final IVector2 point); @Override boolean isPointInShape(final IVector2 point, final double margin); @Override boolean isPointInShapeOrBehind(final IVector2 point); @Override IVector2 nearestPointInside(final IVector2 point); @Override IVector2 nearestPointOutside(final IVector2 point); @Override boolean isIntersectingWithLine(final ILine line); @Override boolean isBehindPenaltyArea(final IVector2 point); @Override IVector2 getGoalCenter(); @Override Rectangle getRectangle(); @Override IVector2 getNegCorner(); @Override IVector2 getPosCorner(); @Override List<IDrawableShape> getDrawableShapes(); @Override double distanceTo(final IVector2 point); @Override double distanceToNearestPointOutside(final IVector2 pos); @Override double intersectionArea(final IVector2 from, final IVector2 to);  }