một vòng tròn Bresenham ở Scala (35)
Thuật toán Bresenham có 2 điểm chính:
- hoạt động mà không có tội lỗi / cosin.
- bạn chỉ tính vòng tròn ¼ *, các điểm khác được tìm thấy bằng cách phản chiếu.
Làm thế nào để làm nó:
2 1
DCBABCD
GFE | EFG
IJ y | ---- JI
GJ | / JG
F | / | F
DE | r / | ED
C | / | C
B 4 | / | B 3
A + ------- A
B 4 'x B 3'
CC
DE ED
FF
GJ JG
IJ JI
GFE EFG
DCBABCD
2'1 '
- Chúng tôi chỉ tính các số từ A trong zenit đến I.
- Điểm I nằm ở 45 °, được xác định bởi x == y.
- Mặt đất bằng 0 là nơi + là.
- Điểm A trong zenit là điểm (x = 0, y = r), r = radius.
- Để vẽ một vòng tròn khép kín, chúng ta di chuyển theo chiều kim đồng hồ (++ x), nằm bên phải (x + = 1) hoặc xuống điểm tiếp theo, (y- = 1).
- mọi điểm (x, y) trên đường tròn đều r cách tâm. Pythagoras nói, r² = x² + y².
- Điều này có mùi giống như căn bậc hai và phương trình với 2 giải pháp, nhưng hãy cẩn thận!
- chúng ta bắt đầu tại A và muốn biết, liệu chúng ta vẽ tiếp theo điểm bên dưới hay điểm bên dưới bên phải.
- chúng tôi tính toán cho cả hai điểm (x² + y²) và xây dựng cho cả sự khác biệt so với r² (tất nhiên là không đổi).
- vì sự khác biệt có thể là tiêu cực, chúng tôi lấy abs từ nó.
- sau đó chúng ta xem điểm nào gần với kết quả hơn (r²), eo ipso nhỏ hơn.
- tùy thuộc vào đó chúng ta vẽ hàng xóm bên phải hoặc dưới cùng.
- điểm được tìm thấy
- 1 x, y được nhân đôi
- 2 -x, y ở bên trái
- 3 y, x tại đường chéo
- 4 -y, x từ đó sang trái
- tất cả những điểm đó được nhân đôi một lần nữa ở phía nam
- 1 'x, -y
- 2 '-x, -y
- 3 'y, -x
- 4 '-y, -x xong.
Đây không phải là mã golf, nhưng tất cả những con số đứng đầu các giải pháp hiện có khiến tôi nghĩ nó là vậy, vì vậy tôi đã dành thời gian vô ích để chơi golf giải pháp của mình. Vì vậy, tôi đã thêm một số vô dụng ở đầu quá. Đó là 11 lần Pi tròn.
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"))
}
Câu hỏi về phông chữ được quyết định bởi máy chủ web của trang web và cài đặt trình duyệt của bạn. Bây giờ, tôi đang tìm kiếm nó
'Droid Sans Mono',Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif
Cỡ chữ là 12px. Thông tin khá vô dụng, nếu bạn hỏi tôi, nhưng ai làm?
Phần thưởng: hình elip và sản lượng mẫu:
Cầu nguyện là
scala BresenhamCircle SIZE RATIO
ví dụ
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
Tôi đã giới hạn tham số tỷ lệ cho Int để giữ cho nó đơn giản, nhưng nó có thể dễ dàng được mở rộng để cho phép nổi.