스칼라의 브레 센햄 서클 (35)
Bresenham-알고리즘에는 2 가지 주요 포인트가 있습니다.
- 죄 / 코사인없이 작동합니다.
- ¼ * ½ 원만 계산하고 다른 점은 미러링으로 찾습니다.
그것을하는 방법 :
2 1
DCBABCD
GFE | EFG
아이 제이 y | ---- JI
GJ | / JG
F | / | F
DE | r / | ED
C | / | 씨
B 4 | / | B 3
A + ------- A
B 4 'x B 3'
CC
드 에드
FF
GJ JG
이지 지
GFE EFG
DCBABCD
2'1 '
- 제니트의 A부터 I까지의 숫자 만 계산합니다.
- 점 I은 45 °에 있으며 x == y로 정의됩니다.
- 그라운드 제로는 +가있는 곳입니다.
- 제니트의 A는 점 (x = 0, y = r), r = 반지름입니다.
- 닫힌 원을 그리려면 시계 방향 (++ x)으로 오른쪽 (x + = 1) 또는 다음 지점 (y- = 1)으로 이동합니다.
- 원의 모든 점 (x, y)은 중심에서 r 떨어져 있습니다. 피타고라스는 r² = x² + y²라고 말합니다.
- 이 솔루션은 제곱근 냄새와 2 가지 해결책이 있지만
- 우리는 A에서 시작하여 다음 지점 아래 또는 오른쪽 아래 지점을 페인트할지 여부를 알고 싶습니다.
- 우리는 두 점 (x² + y²)을 계산하고 r² (물론 일정하게 유지됨)과의 차이를 계산합니다.
- 그 차이는 부정적 일 수 있기 때문에 우리는 그것으로부터 복근을 취합니다.
- 그러면 우리는 어느 지점이 결과에 더 가까운 지 (r²), 더 작게 볼 수 있습니다.
- 그에 따라 오른쪽 또는 아래쪽 이웃을 그립니다.
- 발견 된 요점
- 1 x, y가 미러링 됨
- 왼쪽에 2 -x, y
- 대각선에서 3, x
- 4 -y, x 왼쪽에서 왼쪽으로
- 모든 점들이 남쪽으로 다시 미러링됩니다
- 1 'x, -y
- 2 '-x, -y
- 3 'y, -x
- 4 '-y, -x 완료
이것은 코드 골프가 아니지만 기존 솔루션의 최상위에있는 모든 숫자로 인해 그렇게 생각했기 때문에 솔루션을 골프에 쓸모없는 시간을 보냈습니다. 따라서 상단에도 쓸모없는 숫자를 추가했습니다. 파이가 반올림 된 것은 11 배입니다.
object BresenhamCircle extends App {
var count = 0
val r = args(0).toInt
// ratio > 1 means expansion in horizontal direction
val ratio = args(1).toInt
val field = ((0 to 2 * r).map (i=> (0 to 2 * r * ratio).map (j=> ' ').toArray)).toArray
def square (x: Int, y: Int): Int = x * x + y * y
def setPoint (x: Int, y: Int) {
field (x)(y*ratio) = "Bresenham"(count)
field (y)(x*ratio) = "Bresenham"(count)
}
def points (x: Int, y: Int)
{
setPoint (r + x, r + y)
setPoint (r - x, r + y)
setPoint (r + x, r - y)
setPoint (r - x, r - y)
}
def bresenwalk () {
var x = 0;
var y = r;
val rxr = r * r
points (x, y);
do
{
val (dx, dy) = { if (math.abs (rxr - square ((x+1), y)) < math.abs (rxr - square (x, (y-1))))
(1, 0)
else
(0, -1)
}
count = (count + 1) % "Bresenham".length
x += dx
y += dy
points (x, y)
}while ((x <= y))
}
bresenwalk ()
println (field.map (_.mkString ("")).mkString ("\n"))
}
글꼴 질문은 사이트 웹 서버 및 브라우저 설정에 따라 결정됩니다. 이제 내가보고있는 것은
'Droid Sans Mono',Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif
글꼴 크기는 12px입니다. 물어 보면 쓸모없는 정보인데 누가합니까?
보너스 : 타원 및 샘플 출력 :
호출은
scala BresenhamCircle SIZE RATIO
예를 들어
scala BresenhamCircle 10 2
s e r B r e s
h n e e n h
e m a a m e
e r r e
m m
h a a h
n n
s e e s
e e
r r
B B
r r
e e
s e e s
n n
h a a h
m m
e r r e
e m a a m e
h n e e n h
s e r B r e s
A ratio of 2 will print a circular shape for most fonts which happen to be about twice as tall than wide. To compensate for that, we widen by 2.
# As smaller value than 2 only 1 is available:
scala BresenhamCircle 6 1
erBre
aes sea
ah ha
e e
es se
r r
B B
r r
es se
e e
ah ha
aes sea
erBre
# widening it has more freedom:
scala BresenhamCircle 12 5
s e r B r e s
a h n e e n h a
B m m B
e r r e
e s s e
B r r B
a m m a
h h
n n
s e e s
e e
r r
B B
r r
e e
s e e s
n n
h h
a m m a
B r r B
e s s e
e r r e
B m m B
a h n e e n h a
s e r B r e s
Int의 비율 매개 변수를 단순하게 유지하도록 제한했지만 부동 소수점을 허용하도록 쉽게 확장 할 수 있습니다.