ein Bresenham-Kreis in der Scala (35)
Der Bresenham - Algorithmus hat 2 Hauptpunkte:
- arbeitet ohne Sünde / Cosinus.
- Sie berechnen nur ¼ * ½ Kreis, die anderen Punkte werden durch Spiegeln gefunden.
Wie es geht:
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 '
- Wir berechnen nur die Zahlen von A im Zenit bis I.
- Punkt I liegt bei 45 °, definiert durch x == y.
- Ground Zero ist dort, wo das + ist.
- Das A im Zenit ist der Punkt (x = 0, y = r), r = Radius.
- Um einen geschlossenen Kreis zu zeichnen, bewegen wir uns im Uhrzeigersinn (++ x) nach rechts (x + = 1) oder nach unten zum nächsten Punkt (y- = 1).
- Jeder Punkt (x, y) auf dem Kreis ist r vom Zentrum entfernt. Pythagoras sagt, r² = x² + y².
- Dies riecht nach Quadratwurzel und Equitations mit 2 Lösungen, aber Vorsicht!
- Wir beginnen bei A und wollen wissen, ob wir als nächstes den Punkt darunter oder den Punkt darunter rechts malen.
- Wir berechnen für beide Punkte (x² + y²) und bauen für beide die Differenz zu r² (die natürlich konstant bleibt).
- Da der Unterschied negativ sein kann, nehmen wir die Bauchmuskeln daraus.
- dann schauen wir, welcher Punkt näher am Ergebnis liegt (r²), eo ipso kleiner.
- je nachdem zeichnen wir den rechten oder unteren nachbarn.
- der so gefundene Punkt
- 1 x, y wird gespiegelt
- 2 -x, y nach links
- 3 y, x in der Diagonale
- 4 -y, x von dort nach links
- Alle diese Punkte werden im Süden wieder gespiegelt
- 1 'x, -y
- 2 '-x, -y
- 3 'y, -x
- 4 '-y, -x fertig.
Dies ist kein Code-Golf, aber all diese Zahlen an der Spitze der vorhandenen Lösungen ließen mich denken, dass dies der Fall ist, und so verbrachte ich nutzlose Zeit damit, meine Lösung zu spielen. Deshalb habe ich auch oben eine nutzlose Nummer hinzugefügt. Es ist 11 mal Pi gerundet.
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"))
}
Die Schriftartfrage wird vom Webserver der Website und Ihren Browsereinstellungen festgelegt. Nun, da ich es sehe, ist es
'Droid Sans Mono',Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif
Die Schriftgröße beträgt 12px. Ziemlich nutzlose Informationen, wenn Sie mich fragen, aber wer tut das?
Bonus: Ellipsen und Probenausgabe:
Der Aufruf ist
scala BresenhamCircle SIZE RATIO
zum Beispiel
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
Ich habe den Ratio-Parameter für Int eingeschränkt, um ihn einfach zu halten, aber er kann leicht erweitert werden, um Floats zu ermöglichen.