From e8d3bebe963a421aece5918c8ae73ca5402dc495 Mon Sep 17 00:00:00 2001 From: dinishajais Date: Mon, 28 Jul 2025 01:10:20 +0530 Subject: [PATCH 1/5] Improvement for BresenhamLine #6437 --- .../thealgorithms/geometry/BresenhamLine.java | 69 ------------------- .../geometry/BresenhamLineStrategy.java | 37 ++++++++++ .../thealgorithms/geometry/LineDrawer.java | 20 ++++++ .../geometry/LineDrawingStrategy.java | 8 +++ .../geometry/BresenhamLineTest.java | 57 --------------- .../geometry/LineDrawerTest.java | 58 ++++++++++++++++ 6 files changed, 123 insertions(+), 126 deletions(-) delete mode 100644 src/main/java/com/thealgorithms/geometry/BresenhamLine.java create mode 100644 src/main/java/com/thealgorithms/geometry/BresenhamLineStrategy.java create mode 100644 src/main/java/com/thealgorithms/geometry/LineDrawer.java create mode 100644 src/main/java/com/thealgorithms/geometry/LineDrawingStrategy.java delete mode 100644 src/test/java/com/thealgorithms/geometry/BresenhamLineTest.java create mode 100644 src/test/java/com/thealgorithms/geometry/LineDrawerTest.java diff --git a/src/main/java/com/thealgorithms/geometry/BresenhamLine.java b/src/main/java/com/thealgorithms/geometry/BresenhamLine.java deleted file mode 100644 index 51d9930c0250..000000000000 --- a/src/main/java/com/thealgorithms/geometry/BresenhamLine.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.thealgorithms.geometry; - -import java.awt.Point; -import java.util.ArrayList; -import java.util.List; - -/** - * The {@code BresenhamLine} class implements the Bresenham's line algorithm, - * which is an efficient way to determine the points of a straight line - * between two given points in a 2D space. - * - *

This algorithm uses integer arithmetic to calculate the points, - * making it suitable for rasterization in computer graphics.

- * - * For more information, please visit {@link https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm} - */ -public final class BresenhamLine { - - private BresenhamLine() { - // Private constructor to prevent instantiation. - } - - /** - * Finds the list of points that form a straight line between two endpoints. - * - * @param x0 the x-coordinate of the starting point - * @param y0 the y-coordinate of the starting point - * @param x1 the x-coordinate of the ending point - * @param y1 the y-coordinate of the ending point - * @return a {@code List} containing all points on the line - */ - public static List findLine(int x0, int y0, int x1, int y1) { - List line = new ArrayList<>(); - - // Calculate differences and steps for each axis - int dx = Math.abs(x1 - x0); // Change in x - int dy = Math.abs(y1 - y0); // Change in y - int sx = (x0 < x1) ? 1 : -1; // Step in x direction - int sy = (y0 < y1) ? 1 : -1; // Step in y direction - int err = dx - dy; // Initial error term - - // Loop until we reach the endpoint - while (true) { - line.add(new Point(x0, y0)); // Add current point to the line - - // Check if we've reached the endpoint - if (x0 == x1 && y0 == y1) { - break; // Exit loop if endpoint is reached - } - - // Calculate error term doubled for decision making - final int e2 = err * 2; - - // Adjust x coordinate if necessary - if (e2 > -dy) { - err -= dy; // Update error term - x0 += sx; // Move to next point in x direction - } - - // Adjust y coordinate if necessary - if (e2 < dx) { - err += dx; // Update error term - y0 += sy; // Move to next point in y direction - } - } - - return line; // Return the list of points forming the line - } -} diff --git a/src/main/java/com/thealgorithms/geometry/BresenhamLineStrategy.java b/src/main/java/com/thealgorithms/geometry/BresenhamLineStrategy.java new file mode 100644 index 000000000000..efce9f33df60 --- /dev/null +++ b/src/main/java/com/thealgorithms/geometry/BresenhamLineStrategy.java @@ -0,0 +1,37 @@ +package com.thealgorithms.geometry; + +import java.awt.Point; +import java.util.ArrayList; +import java.util.List; + +public class BresenhamLineStrategy implements LineDrawingStrategy { + + @Override + public List findLine(int x0, int y0, int x1, int y1) { + List line = new ArrayList<>(); + + int dx = Math.abs(x1 - x0); + int dy = Math.abs(y1 - y0); + int sx = (x0 < x1) ? 1 : -1; + int sy = (y0 < y1) ? 1 : -1; + int err = dx - dy; + + while (true) { + line.add(new Point(x0, y0)); + if (x0 == x1 && y0 == y1) break; + + int e2 = err * 2; + + if (e2 > -dy) { + err -= dy; + x0 += sx; + } + if (e2 < dx) { + err += dx; + y0 += sy; + } + } + + return line; + } +} diff --git a/src/main/java/com/thealgorithms/geometry/LineDrawer.java b/src/main/java/com/thealgorithms/geometry/LineDrawer.java new file mode 100644 index 000000000000..df60002b13c6 --- /dev/null +++ b/src/main/java/com/thealgorithms/geometry/LineDrawer.java @@ -0,0 +1,20 @@ +package com.thealgorithms.geometry; + +import java.awt.Point; +import java.util.List; + +public class LineDrawer { + private LineDrawingStrategy strategy; + + public LineDrawer(LineDrawingStrategy strategy) { + this.strategy = strategy; + } + + public void setStrategy(LineDrawingStrategy strategy) { + this.strategy = strategy; + } + + public List drawLine(int x0, int y0, int x1, int y1) { + return strategy.findLine(x0, y0, x1, y1); + } +} diff --git a/src/main/java/com/thealgorithms/geometry/LineDrawingStrategy.java b/src/main/java/com/thealgorithms/geometry/LineDrawingStrategy.java new file mode 100644 index 000000000000..8c2aa48a2f5b --- /dev/null +++ b/src/main/java/com/thealgorithms/geometry/LineDrawingStrategy.java @@ -0,0 +1,8 @@ +package com.thealgorithms.geometry; + +import java.awt.Point; +import java.util.List; + +public interface LineDrawingStrategy { + List findLine(int x0, int y0, int x1, int y1); +} diff --git a/src/test/java/com/thealgorithms/geometry/BresenhamLineTest.java b/src/test/java/com/thealgorithms/geometry/BresenhamLineTest.java deleted file mode 100644 index 9df308497ddf..000000000000 --- a/src/test/java/com/thealgorithms/geometry/BresenhamLineTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.thealgorithms.geometry; - -import java.awt.Point; -import java.util.Collection; -import java.util.List; -import java.util.stream.Stream; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -/** - * The {@code BresenhamLineTest} class contains unit tests for the - * {@code BresenhamLine} class, specifically testing the - * {@code findLine} method. - * - *

This class uses parameterized tests to validate the output of - * Bresenham's line algorithm for various input points.

- */ -class BresenhamLineTest { - - /** - * Provides test cases for the parameterized test. - * - *

Each test case includes starting coordinates, ending coordinates, - * and the expected collection of points that should be generated by the - * {@code findLine} method.

- * - * @return a stream of arguments containing test cases - */ - static Stream linePointsProvider() { - return Stream.of(Arguments.of(0, 0, 5, 5, List.of(new Point(0, 0), new Point(1, 1), new Point(2, 2), new Point(3, 3), new Point(4, 4), new Point(5, 5))), Arguments.of(0, 0, 5, 0, List.of(new Point(0, 0), new Point(1, 0), new Point(2, 0), new Point(3, 0), new Point(4, 0), new Point(5, 0))), - Arguments.of(0, 0, 0, 5, List.of(new Point(0, 0), new Point(0, 1), new Point(0, 2), new Point(0, 3), new Point(0, 4), new Point(0, 5))), Arguments.of(-2, -2, -5, -5, List.of(new Point(-2, -2), new Point(-3, -3), new Point(-4, -4), new Point(-5, -5))), - Arguments.of(-1, -1, 2, 2, List.of(new Point(-1, -1), new Point(0, 0), new Point(1, 1), new Point(2, 2))), Arguments.of(2, -1, -1, -4, List.of(new Point(2, -1), new Point(1, -2), new Point(0, -3), new Point(-1, -4)))); - } - - /** - * Tests the {@code findLine} method of the {@code BresenhamLine} class. - * - *

This parameterized test runs multiple times with different sets of - * starting and ending coordinates to validate that the generated points - * match the expected output.

- * - * @param x0 the x-coordinate of the starting point - * @param y0 the y-coordinate of the starting point - * @param x1 the x-coordinate of the ending point - * @param y1 the y-coordinate of the ending point - * @param expected a collection of expected points that should form a line - */ - @ParameterizedTest - @MethodSource("linePointsProvider") - void testFindLine(int x0, int y0, int x1, int y1, Collection expected) { - List actual = BresenhamLine.findLine(x0, y0, x1, y1); - Assertions.assertEquals(expected.size(), actual.size(), "The size of the points list should match."); - Assertions.assertTrue(expected.containsAll(actual) && actual.containsAll(expected), "The points generated should match the expected points."); - } -} diff --git a/src/test/java/com/thealgorithms/geometry/LineDrawerTest.java b/src/test/java/com/thealgorithms/geometry/LineDrawerTest.java new file mode 100644 index 000000000000..8cb4da686a65 --- /dev/null +++ b/src/test/java/com/thealgorithms/geometry/LineDrawerTest.java @@ -0,0 +1,58 @@ +package com.thealgorithms.geometry; + +import java.awt.Point; +import java.util.Collection; +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + + +/** + * Unit tests for the LineDrawer using BresenhamLineStrategy. + */ +class LineDrawerTest { + + /** + * Provides test data for drawing lines using the Bresenham algorithm. + */ + static Stream linePointsProvider() { + return Stream.of(Arguments.of(0, 0, 5, 5, List.of(new Point(0, 0), new Point(1, 1), new Point(2, 2), new Point(3, 3), new Point(4, 4), new Point(5, 5))), Arguments.of(0, 0, 5, 0, List.of(new Point(0, 0), new Point(1, 0), new Point(2, 0), new Point(3, 0), new Point(4, 0), new Point(5, 0))), + Arguments.of(0, 0, 0, 5, List.of(new Point(0, 0), new Point(0, 1), new Point(0, 2), new Point(0, 3), new Point(0, 4), new Point(0, 5))), Arguments.of(-2, -2, -5, -5, List.of(new Point(-2, -2), new Point(-3, -3), new Point(-4, -4), new Point(-5, -5))), + Arguments.of(-1, -1, 2, 2, List.of(new Point(-1, -1), new Point(0, 0), new Point(1, 1), new Point(2, 2))), Arguments.of(2, -1, -1, -4, List.of(new Point(2, -1), new Point(1, -2), new Point(0, -3), new Point(-1, -4)))); + } + + /** + * Tests line drawing using the BresenhamLineStrategy through LineDrawer. + */ + @ParameterizedTest + @MethodSource("linePointsProvider") + void testLineDrawingWithBresenhamStrategy(int x0, int y0, int x1, int y1, Collection expected) { + LineDrawingStrategy strategy = new BresenhamLineStrategy(); + LineDrawer drawer = new LineDrawer(strategy); + + List actual = drawer.drawLine(x0, y0, x1, y1); + + Assertions.assertEquals(expected.size(), actual.size(), "Point count mismatch."); + Assertions.assertTrue(expected.containsAll(actual) && actual.containsAll(expected), "Generated points do not match expected points."); + } + + /** + * Demonstrates dynamic strategy switching. + */ + @ParameterizedTest + @MethodSource("linePointsProvider") + void testSetStrategyDynamicSwitch(int x0, int y0, int x1, int y1, Collection expected) { + LineDrawer drawer = new LineDrawer(new BresenhamLineStrategy()); + + // Simulate switching strategy at runtime (e.g., in future: drawer.setStrategy(new DdaLineStrategy())) + drawer.setStrategy(new BresenhamLineStrategy()); // No-op here but shows extensibility + + List actual = drawer.drawLine(x0, y0, x1, y1); + + Assertions.assertEquals(expected.size(), actual.size(), "Point count mismatch after strategy switch."); + Assertions.assertTrue(expected.containsAll(actual) && actual.containsAll(expected), "Generated points do not match expected points after strategy switch."); + } +} From 7d74d42647a79f237533e45577abce1d44727a16 Mon Sep 17 00:00:00 2001 From: dinishajais Date: Mon, 28 Jul 2025 01:51:23 +0530 Subject: [PATCH 2/5] Formatting changes --- .../com/thealgorithms/geometry/BresenhamLineStrategy.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/thealgorithms/geometry/BresenhamLineStrategy.java b/src/main/java/com/thealgorithms/geometry/BresenhamLineStrategy.java index efce9f33df60..0a954e23b693 100644 --- a/src/main/java/com/thealgorithms/geometry/BresenhamLineStrategy.java +++ b/src/main/java/com/thealgorithms/geometry/BresenhamLineStrategy.java @@ -18,8 +18,9 @@ public List findLine(int x0, int y0, int x1, int y1) { while (true) { line.add(new Point(x0, y0)); - if (x0 == x1 && y0 == y1) break; - + if (x0 == x1 && y0 == y1) { + break; + } int e2 = err * 2; if (e2 > -dy) { From 9891e31e57a0afd7d12fb90d47085084eaf883c6 Mon Sep 17 00:00:00 2001 From: dinishajais Date: Mon, 28 Jul 2025 01:58:03 +0530 Subject: [PATCH 3/5] formatting changes --- src/test/java/com/thealgorithms/geometry/LineDrawerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/thealgorithms/geometry/LineDrawerTest.java b/src/test/java/com/thealgorithms/geometry/LineDrawerTest.java index 8cb4da686a65..cafc75f8bf36 100644 --- a/src/test/java/com/thealgorithms/geometry/LineDrawerTest.java +++ b/src/test/java/com/thealgorithms/geometry/LineDrawerTest.java @@ -13,7 +13,7 @@ /** * Unit tests for the LineDrawer using BresenhamLineStrategy. */ -class LineDrawerTest { + class LineDrawerTest { /** * Provides test data for drawing lines using the Bresenham algorithm. From 3e525154b082fdd4907ea9874d93ddda76ae0fc3 Mon Sep 17 00:00:00 2001 From: dinishajais Date: Mon, 28 Jul 2025 02:01:04 +0530 Subject: [PATCH 4/5] formatting changes --- src/test/java/com/thealgorithms/geometry/LineDrawerTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/java/com/thealgorithms/geometry/LineDrawerTest.java b/src/test/java/com/thealgorithms/geometry/LineDrawerTest.java index cafc75f8bf36..57f0239ea2a0 100644 --- a/src/test/java/com/thealgorithms/geometry/LineDrawerTest.java +++ b/src/test/java/com/thealgorithms/geometry/LineDrawerTest.java @@ -9,11 +9,10 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; - /** * Unit tests for the LineDrawer using BresenhamLineStrategy. */ - class LineDrawerTest { +class LineDrawerTest { /** * Provides test data for drawing lines using the Bresenham algorithm. From 311643739195cf59eb87d19b814318aac0125021 Mon Sep 17 00:00:00 2001 From: dinishajais Date: Mon, 28 Jul 2025 02:14:14 +0530 Subject: [PATCH 5/5] Formatting --- src/test/java/com/thealgorithms/geometry/LineDrawerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/thealgorithms/geometry/LineDrawerTest.java b/src/test/java/com/thealgorithms/geometry/LineDrawerTest.java index 57f0239ea2a0..5e7f304a9790 100644 --- a/src/test/java/com/thealgorithms/geometry/LineDrawerTest.java +++ b/src/test/java/com/thealgorithms/geometry/LineDrawerTest.java @@ -34,7 +34,7 @@ void testLineDrawingWithBresenhamStrategy(int x0, int y0, int x1, int y1, Collec List actual = drawer.drawLine(x0, y0, x1, y1); - Assertions.assertEquals(expected.size(), actual.size(), "Point count mismatch."); + Assertions.assertEquals(expected.size(), actual.size(), "Points count mismatch."); Assertions.assertTrue(expected.containsAll(actual) && actual.containsAll(expected), "Generated points do not match expected points."); }