Skip to content
This repository was archived by the owner on Jul 26, 2025. It is now read-only.

Commit ad97cb8

Browse files
committed
feat: implement getFilledCirclePoints
1 parent 2bb1c6d commit ad97cb8

File tree

3 files changed

+57
-10
lines changed

3 files changed

+57
-10
lines changed
94 Bytes
Loading

src/utils/geometry/__tests__/getCirclePoints.test.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { Image } from '../../../Image';
2+
import { ImageColorModel } from '../../constants/colorModels';
13
import {
24
getCirclePoints,
35
getCompassPoints,
@@ -77,10 +79,45 @@ test('horizonal line', () => {
7779
});
7880

7981
test('filled circle with radius 1', () => {
80-
expect(getFilledCirclePoints(1, { column: 0, row: 0 })).toStrictEqual([
82+
const points = getFilledCirclePoints(1, { column: 0, row: 0 });
83+
84+
expect(points.length).toBe(5);
85+
expect(points).toStrictEqual([
86+
{ row: 0, column: 0 },
8187
{ row: 0, column: 1 },
8288
{ row: 1, column: 0 },
8389
{ row: 0, column: -1 },
8490
{ row: -1, column: 0 },
8591
]);
8692
});
93+
94+
test('filled circle with radius 0', () => {
95+
expect(getFilledCirclePoints(0, { column: 0, row: 0 })).toStrictEqual([
96+
{ row: 0, column: 0 },
97+
]);
98+
});
99+
100+
test('filled circle with radius 5', () => {
101+
const emptyImage = new Image(11, 11, { colorModel: ImageColorModel.GREY });
102+
const center = { row: 5, column: 5 };
103+
104+
const points = getFilledCirclePoints(5, center);
105+
106+
expect(
107+
emptyImage.drawPoints(points, { color: [255] }),
108+
).toMatchImageSnapshot();
109+
110+
expect(emptyImage.drawPoints(points, { color: [255] })).toMatchImage(
111+
emptyImage.drawCircle(center, 5, { fill: [255], color: [255] }),
112+
);
113+
});
114+
115+
test('check for points twice in array', () => {
116+
const emptyImage = new Image(5, 5, { colorModel: ImageColorModel.GREY });
117+
const points = getFilledCirclePoints(2, { column: 0, row: 0 });
118+
119+
expect(points.length).toBe(21);
120+
expect(
121+
emptyImage.drawPoints(points, { color: [255] }),
122+
).toMatchImageSnapshot();
123+
});

src/utils/geometry/getCirclePoints.ts

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { circle, line } from 'bresenham-zingl';
33
import { Point } from '../../geometry';
44

55
/**
6-
* Get the coordinates of the points on a circle. The reference is the origin of the circle.
6+
* Get the coordinates of the points on a circle. The reference is the center of the circle.
77
* The first point is the right one and they are then sorted clockwise.
88
*
99
* @param radius - Radius of the circle.
@@ -37,24 +37,34 @@ export function getCirclePoints(radius: number): Point[] {
3737
* @param center - Center of the cirlce.
3838
* @returns The coordinates of the points in a circle of given radius.
3939
*/
40-
export function getFilledCirclePoints(radius: number, center: Point): Point[] {
40+
export function getFilledCirclePoints(
41+
radius: number,
42+
center: Point = { column: 0, row: 0 },
43+
): Point[] {
4144
let circlePoints: Point[] = [];
4245

46+
if (radius === 0) {
47+
return [center];
48+
}
4349
if (radius === 1) {
4450
circlePoints.push(center);
4551
}
4652
circle(center.column, center.row, radius, (column: number, row: number) => {
47-
circlePoints.push({ row: row - radius, column: column - radius });
53+
circlePoints.push({ row, column });
4854

4955
if (column - 1 > center.column) {
50-
getLinePoints(
51-
{ row, column: column - 1 },
52-
{ row, column: center.column },
56+
circlePoints.push(
57+
...getLinePoints(
58+
{ row, column: column - 1 },
59+
{ row, column: center.column },
60+
),
5361
);
5462
} else if (column + 1 < center.column) {
55-
getLinePoints(
56-
{ row, column: column + 1 },
57-
{ row, column: center.column },
63+
circlePoints.push(
64+
...getLinePoints(
65+
{ row, column: column + 1 },
66+
{ row, column: center.column },
67+
),
5868
);
5969
}
6070
});

0 commit comments

Comments
 (0)