-
Notifications
You must be signed in to change notification settings - Fork 20.5k
feat: add bresenham's line drawing algorithm #5779
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
65 changes: 65 additions & 0 deletions
65
src/main/java/com/thealgorithms/geometry/BresenhamLine.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
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. | ||
* | ||
* <p>This algorithm uses integer arithmetic to calculate the points, | ||
* making it suitable for rasterization in computer graphics.</p> | ||
* | ||
* For more information, please visit {@link https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm} | ||
*/ | ||
public final class BresenhamLine { | ||
|
||
/** | ||
* 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<Point>} containing all points on the line | ||
*/ | ||
public List<Point> findLine(int x0, int y0, int x1, int y1) { | ||
List<Point> 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 | ||
int e2 = err * 2; | ||
saahil-mahato marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
// 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 | ||
} | ||
} |
87 changes: 87 additions & 0 deletions
87
src/test/java/com/thealgorithms/geometry/BresenhamLineTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package com.thealgorithms.geometry; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
||
import java.awt.Point; | ||
import java.util.List; | ||
import org.junit.jupiter.api.Test; | ||
|
||
/** | ||
* The {@code BresenhamLineTest} class contains unit tests for the {@code BresenhamLine} class. | ||
* It verifies the correctness of the findLine method, which generates a list of points | ||
* representing a straight line between two specified endpoints. | ||
* | ||
* <p>This test class uses JUnit 5 for testing and covers various scenarios including horizontal, | ||
* vertical, and diagonal lines, as well as lines with negative coordinates.</p> | ||
*/ | ||
class BresenhamLineTest { | ||
saahil-mahato marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// Instance of BresenhamLine to be tested | ||
private final BresenhamLine bresenhamLine = new BresenhamLine(); | ||
|
||
/** | ||
* Tests the generation of a horizontal line from (0, 0) to (5, 0). | ||
* Asserts that the generated line matches the expected list of points. | ||
*/ | ||
@Test | ||
void testHorizontalLine() { | ||
List<Point> line = bresenhamLine.findLine(0, 0, 5, 0); | ||
List<Point> expected = 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)); | ||
assertEquals(expected, line); | ||
} | ||
|
||
/** | ||
* Tests the generation of a vertical line from (0, 0) to (0, 5). | ||
* Asserts that the generated line matches the expected list of points. | ||
*/ | ||
@Test | ||
void testVerticalLine() { | ||
List<Point> line = bresenhamLine.findLine(0, 0, 0, 5); | ||
List<Point> expected = 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)); | ||
assertEquals(expected, line); | ||
} | ||
|
||
/** | ||
* Tests the generation of a diagonal line from (0, 0) to (5, 5). | ||
* Asserts that the generated line matches the expected list of points. | ||
*/ | ||
@Test | ||
void testDiagonalLine() { | ||
List<Point> line = bresenhamLine.findLine(0, 0, 5, 5); | ||
List<Point> expected = 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)); | ||
assertEquals(expected, line); | ||
} | ||
|
||
/** | ||
* Tests the generation of a diagonal line with a negative slope from (5, 5) to (0, 0). | ||
* Asserts that the generated line matches the expected list of points. | ||
*/ | ||
@Test | ||
void testNegativeSlopeDiagonal() { | ||
List<Point> line = bresenhamLine.findLine(5, 5, 0, 0); | ||
List<Point> expected = List.of(new Point(5, 5), new Point(4, 4), new Point(3, 3), new Point(2, 2), new Point(1, 1), new Point(0, 0)); | ||
assertEquals(expected, line); | ||
} | ||
|
||
/** | ||
* Tests the generation of a steep vertical line from (1, 1) to (1, 4). | ||
* Asserts that the generated line matches the expected list of points. | ||
*/ | ||
@Test | ||
void testSteepDiagonal() { | ||
List<Point> line = bresenhamLine.findLine(1, 1, 1, 4); | ||
List<Point> expected = List.of(new Point(1, 1), new Point(1, 2), new Point(1, 3), new Point(1, 4)); | ||
assertEquals(expected, line); | ||
} | ||
|
||
/** | ||
* Tests the generation of a diagonal line with negative coordinates from (-3,-3) to (-1,-1). | ||
* Asserts that the generated line matches the expected list of points. | ||
*/ | ||
@Test | ||
void testMixedCoordinates() { | ||
List<Point> line = bresenhamLine.findLine(-3, -3, -1, -1); | ||
List<Point> expected = List.of(new Point(-3, -3), new Point(-2, -2), new Point(-1, -1)); | ||
assertEquals(expected, line); | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.