waaaay better circles

This commit is contained in:
Stefan Harmuth 2022-08-14 13:36:55 +02:00
parent 987a5bab28
commit 3c5e27cf36

View File

@ -1,9 +1,11 @@
from __future__ import annotations
from dataclasses import dataclass
from enum import Enum
from math import gcd, sqrt, inf, atan2, degrees
from math import gcd, sqrt, inf, atan2, degrees, floor
from typing import Union, List, Optional
from tools.math import round_half_up
class DistanceAlgorithm(Enum):
MANHATTAN = 0
@ -65,8 +67,9 @@ class Coordinate:
else:
return minX <= self.x <= maxX and minY <= self.y <= maxY and minZ <= self.z <= maxZ
def getCircle(self, radius: int = 1, includeDiagonal: bool = True, minX: int = -inf, minY: int = -inf,
maxX: int = inf, maxY: int = inf, minZ: int = -inf, maxZ: int = inf) -> list[Coordinate]:
def getCircle(self, radius: int = 1, algorithm: DistanceAlgorithm = DistanceAlgorithm.EUCLIDEAN,
minX: int = -inf, minY: int = -inf, maxX: int = inf, maxY: int = inf,
minZ: int = -inf, maxZ: int = inf) -> list[Coordinate]:
# FIXME: includeDiagonal == True returns way too few coordinates
ret = []
if self.z is None: # mode 2D
@ -75,9 +78,10 @@ class Coordinate:
target = Coordinate(x, y)
if not target.inBoundaries(minX, minY, maxX, maxY):
continue
dist = self.getDistanceTo(target, DistanceAlgorithm.MANHATTAN, includeDiagonals=includeDiagonal)
dist = round_half_up(self.getDistanceTo(target, algorithm=algorithm, includeDiagonals=False))
if dist == radius:
ret.append(target)
else:
for x in range(self.x - radius * 2, self.x + radius * 2 + 1):
for y in range(self.y - radius * 2, self.y + radius * 2 + 1):