a Bresenham circle in Scala (35)
Algoritma Bresenham - memiliki 2 poin utama:
- bekerja tanpa dosa / cosin.
- Anda hanya menghitung ¼ * ½ lingkaran, titik-titik lainnya ditemukan dengan mirroring.
Bagaimana cara melakukannya:
2 1
DCBABCD
GFE | EFG
IJ y | ---- JI
GJ | /J G
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 '
- Kami hanya menghitung angka dari A di zenit hingga I.
- Titik I pada 45 °, didefinisikan oleh x == y.
- Ground zero adalah tempat + berada.
- A dalam zenit adalah titik (x = 0, y = r), r = jari-jari.
- Untuk menggambar lingkaran tertutup kita bergerak searah jarum jam (++ x), yaitu ke kanan (x + = 1) atau turun ke titik berikutnya, (y- = 1).
- setiap titik (x, y) pada lingkaran adalah r jauh dari pusat. Pythagoras mengatakan, r² = x² + y².
- Baunya seperti akar kuadrat dan persamaan dengan 2 solusi, tapi waspadalah!
- kita mulai dari A dan ingin tahu, apakah kita melukis titik berikutnya di bawah atau titik di bawah kanan.
- kami menghitung untuk kedua titik (x² + y²) dan membangun untuk kedua perbedaan menjadi r² (yang tetap tentu saja konstan).
- karena perbedaannya bisa negatif, kami mengambil abs darinya.
- lalu kita lihat titik mana yang lebih dekat dengan hasil (r²), eo ipso lebih kecil.
- tergantung pada yang kita gambar tetangga kanan atau bawah.
- titik yang ditemukan
- 1 x, kamu dicerminkan
- 2 -x, y ke kiri
- 3 y, x di diagonal
- 4 -y, x dari sana ke kiri
- semua titik dicerminkan lagi ke selatan
- 1 'x, -y
- 2 '-x, -y
- 3 'y, -x
- 4 '-y, -x selesai.
Ini bukan kode golf, tetapi semua angka di atas solusi yang ada membuat saya berpikir begitu, jadi saya menghabiskan waktu yang tidak berguna dalam bermain golf solusi saya. Karena itu saya menambahkan nomor yang tidak berguna di bagian atas juga. Ini 11 kali Pi bulat.
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"))
}
Pertanyaan font ditentukan oleh server situs dan pengaturan browser Anda. Sekarang, yang saya cari itu
'Droid Sans Mono',Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif
Ukuran font adalah 12px. Informasi yang tidak berguna, jika Anda bertanya kepada saya, tetapi siapa yang tahu?
Bonus: elips dan output sampel:
Doa adalah
scala BresenhamCircle SIZE RATIO
sebagai contoh
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
Saya membatasi parameter rasio untuk Int agar tetap sederhana, tetapi dapat dengan mudah diperlebar untuk memungkinkan mengapung.