Joopa joo, ei sitten näy nuo vastaukset joten pistänpä vastauksen tähän. Toivottavasti saavat nuo ylläpidon heput bugin fiksattua vielä tänä vuonna (veri opvioosli not...) ;)
>Miten piirrän viisisakaraisen tähden.
>eli tarvitsen tietää asteet miten käännytää
>Neliön tein näin
>CALL rt(90)
>CALL fd(100)
>CALL rt(90)
>CALL fd(100)
>CALL rt(90)
>CALL fd(100)
>CALL rt(90)
>CALL fd(100)
>Mutta tähteä en saa kirveelläkään
Homma menee about näin:
Jokainen sakara on tasakylkinen kolmio. Kun jaetaan 360 astetta (ympyrä) sakaroiden lkm:llä (sakarat), saadaan tulos, montako astetta pitää kääntyä, jotta päästään takaisin lähtöpisteeseen haluttujen askeleiden jälkeen, ts. piirretään monikulmio (tässä 5-kulmio).
Merkitään kolmion eli sakaran korkeutta h:lla ja leveyttä l:llä. Sakara muodostuu siis kolmion kyljistä l. hypotenuusasta (c^2=a^2 b^2). Hypotenuusan ja pohjasivun välinen kulma saadaan modifioimalla kaavasta tan alfa=a/b (alfa-kulman tangentti on kulman vastakkaisen sivun suhde kulman viereiseen sivuun). Varsinainen astekulma saadaan, kun tangentti kerrotaan 180:lla ja jaetaan piillä (kone käyttää radiaaneja eli tehdään muutos rad->deg).
DECLARE SUB piirra (pituus!) 'piirtää viivan
DECLARE SUB kaanna (astetta!) 'kääntää suuntaa asteina (suunnan muutos)
DECLARE SUB suunta (asteet!) 'asettaa suunnan (uusi, absoluuttinen suunta)
SCREEN 12
DIM SHARED astenyt 'pidetään kirjaa nykyisestä suunnasta
pii = ATN(1) * 4 'pii ;)
sakarat = 5 'montako sakaraa tähteen
askel = 360 / sakarat 'montako astetta sakaran pohjasivu kääntyy ympyrän kehällä joka kerta
h = 50 ' sakaran korkeus pisteinä
l = 20 ' sakaran kannan leveys pisteinä
hyp = SQR(h ^ 2 (l / 2) ^ 2) 'sakaran sivun pituus (hypotenuusat, ts. tasakylk. kolmion sivut)
aste = (l / (2 * hyp)) 'kulman tangentti
aste = TAN(aste) * 180 / pii 'kulma asteina
FOR i = 1 TO sakarat 'piirretään sakarat
kaanna (aste) 'eka käännös
piirra (h) 'eka viiva
kaanna (180 - aste * 2) 'toinen käännös
piirra (h) 'toinen viiva
suunta (i * askel) 'käännetään suunta seuraavalle sakaralle
NEXT
SUB kaanna (astetta)
astenyt = (astenyt astetta) MOD 360
DRAW "ta" STR$(INT(astenyt))
END SUB
SUB piirra (pituus)
DRAW "u" STR$(pituus)
END SUB
SUB suunta (asteet)
astenyt = asteet MOD 360
DRAW "ta" STR$(INT(astenyt))
END SUB
>Miten piirrän viisisakaraisen tähden.
>eli tarvitsen tietää asteet miten käännytää
>Neliön tein näin
>CALL rt(90)
>CALL fd(100)
>CALL rt(90)
>CALL fd(100)
>CALL rt(90)
>CALL fd(100)
>CALL rt(90)
>CALL fd(100)
>Mutta tähteä en saa kirveelläkään
Homma menee about näin:
Jokainen sakara on tasakylkinen kolmio. Kun jaetaan 360 astetta (ympyrä) sakaroiden lkm:llä (sakarat), saadaan tulos, montako astetta pitää kääntyä, jotta päästään takaisin lähtöpisteeseen haluttujen askeleiden jälkeen, ts. piirretään monikulmio (tässä 5-kulmio).
Merkitään kolmion eli sakaran korkeutta h:lla ja leveyttä l:llä. Sakara muodostuu siis kolmion kyljistä l. hypotenuusasta (c^2=a^2 b^2). Hypotenuusan ja pohjasivun välinen kulma saadaan modifioimalla kaavasta tan alfa=a/b (alfa-kulman tangentti on kulman vastakkaisen sivun suhde kulman viereiseen sivuun). Varsinainen astekulma saadaan, kun tangentti kerrotaan 180:lla ja jaetaan piillä (kone käyttää radiaaneja eli tehdään muutos rad->deg).
DECLARE SUB piirra (pituus!) 'piirtää viivan
DECLARE SUB kaanna (astetta!) 'kääntää suuntaa asteina (suunnan muutos)
DECLARE SUB suunta (asteet!) 'asettaa suunnan (uusi, absoluuttinen suunta)
SCREEN 12
DIM SHARED astenyt 'pidetään kirjaa nykyisestä suunnasta
pii = ATN(1) * 4 'pii ;)
sakarat = 5 'montako sakaraa tähteen
askel = 360 / sakarat 'montako astetta sakaran pohjasivu kääntyy ympyrän kehällä joka kerta
h = 50 ' sakaran korkeus pisteinä
l = 20 ' sakaran kannan leveys pisteinä
hyp = SQR(h ^ 2 (l / 2) ^ 2) 'sakaran sivun pituus (hypotenuusat, ts. tasakylk. kolmion sivut)
aste = (l / (2 * hyp)) 'kulman tangentti
aste = TAN(aste) * 180 / pii 'kulma asteina
FOR i = 1 TO sakarat 'piirretään sakarat
kaanna (aste) 'eka käännös
piirra (h) 'eka viiva
kaanna (180 - aste * 2) 'toinen käännös
piirra (h) 'toinen viiva
suunta (i * askel) 'käännetään suunta seuraavalle sakaralle
NEXT
SUB kaanna (astetta)
astenyt = (astenyt astetta) MOD 360
DRAW "ta" STR$(INT(astenyt))
END SUB
SUB piirra (pituus)
DRAW "u" STR$(pituus)
END SUB
SUB suunta (asteet)
astenyt = asteet MOD 360
DRAW "ta" STR$(INT(astenyt))
END SUB
Vastaukset 9
Vanhimmat
Pyöristysvirheiden kumuloituminen aiheuttaa sen, että tähden alku- ja loppupää eivät tarkkaan ottaen kohtaa, eikö vain. Tässä tapauksessa asialla ei ehkä ole merkitystä..?
Itse asiassa pyöristysvirhe ei ainakaan omissa testeissä kumuloitunut (ainakaan havaittavasti), sakarat osuvat toisiinsa kuten pitääkin, vaikka käytin moduloa. Alkuun tuo DRAW kyllä aiheutti ikävyyksiä kun ei suostunut huolimaan desimaaleja mutta tuon version pitäisi toimia suht koht OK. Oletko kokeillut tuota pätkää ja löytänyt sopivia alkuarvoja, joilla sakarat menevät päin per...?
Sovellus (laskenta liukuluvuilla, pyöristys kokonaisluvuiksi) sekä toteutus (kunkin pisteen paikka määräytyy suhteessa edelliseen) on tyypillisesti sellainen, jossa virheiden kumuloitumisen vaara on olemassa.
Taas kerran, arvon kollega, asialla ei ole merkitystä kun piirtelee tähtiä omaksi ilokseen ja joulun kunniaksi, mutta kerran kun teet saman AutoCadille tms., joudut miettimään asiat uudesta näkökulmasta.
Ei riitä, että asia NÄYTTÄÄ olevan kunnossa -- sen pitää olla sitä myös teoriassa. Omasta kokemuksesta suosittelen tätä periaatetta ja lähestymistapaa kaikkeen ohjelmointityöhön. Se helpottaa elämää hieman pidemmällä tähtäimellä.
Mutta tässähän oli kyse joulutähdistä, eikö ;-)
Liukulukujen pyöristysvirheet on vähän liiankin tuttuja, asia on tiedossa.
esim float:ia kun kasvattaa silmukassa esim 0.1:llä, asettaa floati:in 2 000 000 001 jne jne
em. kääntö- ja suunnanvaihtoaliohjelmissa käytän pyöristystä VAIN jos kulma menee >=360 astetta tai
On tuota tullut kokeiltua pariin otteeseen. Kirjoitin joskus 286/AT-koneiden aikoihin joukon grafiikkarutiineja erästä sovellusta varten ja kun koneet olivat hitaita, softan piti olla nopeaa. (Ajat ovat muuttuneet... joiltakin osin huonompaan.)
Piirtelimme Bresenhamin algoritmin kaltaisella muunnoksella suoraa viivaa noin kymmenellä asm-käskyllä (loopin koko, pisteen asetuksen lisäksi) ja kuten totesit, viivaa syntyi pirun nopeasti!
Tarkoititko (kokonaislukuversio piirtää viivan paikotellen "huonommin"), että lähes vaakasuoraan viivaan tulee yhden pikselin mutka "väärään kohtaan"? Sehän on erittäin helposti eliminoitavissa myös kokonaislukuja käytettäessä.
>...pikselin mutka "väärään"...
sitäpä hyvinkin. vaan minulle tuo riitti, pääasia oli grafiikan nopeus (sitä sain lisää) enkä sen kummemmin koodia viilannut, mitä nyt C:stä käänsin assyyn (joka ei nopeuteen kovinkaan radikaalisti vaikuttanut. huono ja optimoimaton käännös, n. 15-25 riviä koodia kaikkiaan muistaakseni...) liukulukuja käytettäessä tuo pikkuohjelma (yksink. vektorigrafiikkarutiini) piirsi 386sx 20MHz:lla n. 6 ruutua/sek, 12MHz 286 287:lla n. 15 kuvaa/sek, Pentium MMX 200Mhz Perus-SVGA n. 1600 kuvaa/sek. Jotain hyötyä tuosta matikkalutikasta sentään oli... toki tulokseen vaikutti myös näytönohjain, niiden merkkejä/malleja en enää muista, perus-VGA kuitenkin noissa 286/386-vehkeissä
>koneet olivat hitaita, softan piti olla nopeaa. (Ajat ovat muuttuneet... joiltakin osin huonompaan.)
Kokeilin tuossa joku aika sitten piruuttani veivata pieniä grafiikkarutiineja C64:lle. Siilä vehkeellä assyllä pisteen piirtäminenkin vaatii jo vähän funtsimista verrattuna vaikka PC:llä 320*200 VGA-tilassa piirtelyyn.
> C:stä käänsin assyyn (joka ei nopeuteen
> kovinkaan radikaalisti vaikuttanut. huono ja
> optimoimaton käännös
C-kääntäjät eivät edelleenkään osaa optimoida rekistereiden käyttöä "optimaaliseksi". Yksi harvoja syitä miksi ääritilanteessa on edelleen turvauduttava asm-koodaukseen.
> Kokeilin tuossa joku aika sitten piruuttani
> veivata pieniä grafiikkarutiineja C64:lle.
Aaah, vanha kunnon 6569! Hämmästyttävän paljon siitäkin sai irti kun oli oikeat tekijät asialla. Minä en vääntänyt oikeastaan mitään 64:lle, mutta niille commorojun "ammattikoneille" senkin edestä. 6502:n (ja siis 6510:n) assy löytyisi varmaan edelleenkin selkäytimestä.
Mitä luulet, kannattaisiko jostakin autotallin kätköistä hakea 64 esiin ja piruuttaan kokeilla vaikka viivan piirtoa???
>Mitä luulet, kannattaisiko jostakin autotallin kätköistä hakea 64 esiin ja piruuttaan kokeilla vaikka viivan piirtoa???
Mikäs sen parempi viikonloppuharraste? ;)
Tuttuja?
http://www.hut.fi/Misc/cbm/cbm-msmakela.html