Pää lyö tyhjää. Flashia rakentaessa eteen tuli sellainen tilanne, jossa pitäisi saada tietoon yhden suorakulmaisen kolmion kulman koordinaatit (x,y). Kaikkien sivujen pituudet ja kahden muun kulman (joista toinen on se suorakulma) koordinaatit on tiedossa. Mutta miten sen kolmannen saa?
Tilanne on siis seuraava:
|\ a | \ c | \ ---- b
Sivut a, b ja c tunnetaan, samoin vaikka molemmat vasemman reunan koordinaatit. Eli nyt pitää laskea, missä on sivujen b ja c välinen kulma. Sinne päästään liikkumalla suorakulmasta sivun b pituuden verran suuntaan, joka poikkeaa 90 astetta sivun a tunnetusta suunnasta. Näillä tiedoilla tosin vastaus ei ole yksikäsitteinen, koska yhtä hyvin sivu b voisi lähteä suorakulmasta vasemmalle.
Tilanne on käytännössä aina seuraavanlainen (paitsi, että kolmio on koordinaatistossa nojallaan johonkin suuntaan
- - - a - - c - - - - - - - - - - b
Ja näistä ainoastaan sen ylimmän kulman koordinaatit on tuntemattomia. Niin pitkään, kun sivu b kulkee suoraan x-koordinaatistoa pitkin, hommahan on helppo, mutta sitten, kun kolmiota aletaan kallistelemaan, niin menee vaikeaksi. Ainakin täällä päässä...
Onko napakoordinaatisto tuttu? Muunnat tunnetut koodinaatit napakoordinaateiksi, kierrät kolmion haluttuun kulmaan ja sitten takaisin xy-koordinaateiksi.
Eipä ole tuttuja ei... katsotaan jos ystävämme google osais neuvoa.
Tässä pitäisi olla aika yksinkertainen algoritmi:
1. Laske tunnettujen koordinaattien erotukset (x:n ja y:n erotus).
2. Vaihda erotukset keskenään (x:stä tulee y ja y:stä x).
3. Muuta jompikumpi erotus vastaluvuksi (luvun eteen miinus).
4. Jaa molemmat erotukset kolmion sen sivun pituudella, joka on suorakulman ja toisen tunnetun kulman välillä.
5. Kerro molemmat erotukset kolmion sen sivun pituudella, joka on suorakulman ja tuntemattoman kulman välillä.
6. Lisää näin saadut x:t ja y:t suorakulman koordinaatteihin.
Kohdasta 3 riippuu, kummalle puolelle tuntematon piste ilmestyy.
Esimerkki:
a C - - - - - - - - - - B - - b - - c - A
Sivun pituudet ovat a = 10, b = √10 ja c = √90. Kulma A on suorakulma kohdassa (1, 0), ja kulma C on kohdassa (0, 3). Kulman B koordinaatteja ei vielä tunneta.
1. x = 0 - 1 = -1, y = 3 - 0 = 3.
2. x = 3, y = -1
3. x = 3, y = 1 (toinen vaihtoehto: x = -3, y = -1)
4. x = 3 / √10, y = 1 / √10
5. x = 3 / √10 * √90, y = 1 / √10 * √90
Koska √90 = √9 * √10 = 3 * √10, saadaan:
5. x = 9, y = 3
6. x = 1 + 9 = 10, y = 0 + 3 = 3
Näin saatiin selville, että kulma B on kohdassa (10, 3).
Tietokoneella laskettaessa ei tietenkään tarvitse miettiä neliöjuurten laskusääntöjä, vaan jaot ja kertomiset voi suorittaa saman tien. Tämän algoritmin voi ajatella niin, että sivua, jonka molempien päiden koordinaatit tunnetaan, käännetään ensin 90 astetta, minkä jälkeen venytetään tai kutistetaan sivu oikean pituiseksi ja tutkitaan, mihin koordinaatteihin päästiin.
EDIT: Hidas. Sama asia kuin Antilla.
Viittaan Michin kuvaan, jossa on eri kirjaimet kuin Antin kuvassa.
Olkoot b:n ja c:n leikkauspiste (tai yhteinen kulma) p1 ja b:n toinen pää p2.
Jos määrität sivun b suuntaisen vektorin p1 -> p2, saat siitä sivun c suuntaisen vektorin kääntämällä sitä 90 astetta myötäpäivään. Tämä tapahtuu vaihtamalla x- ja y-koordinaattien paikkaa ja kertomalla uusi y-koordinaatti miinus yhdellä.
Siis esim. vektorin (2,1) kääntö 90 astetta myötäpäivään on (1,-2).
Nyt saat oikeansuuntaisen vektorin. Jos kerrot sen sivujen c ja b pituuksien suhteella, tiedät kuinka pitkälle pitää mennä, että löydät c:n toisen päätepisteen. Jos esim. c:n pituus on 4 ja b:n 2, on c kaksi kertaa pidempi; suhde on 4/2 eli 2. (Käytä reaalilukuaritmetiikkaa.)
Tämä antaa sinulle toisen sivun vektoriesityksen. Löydät halutun pisteen lisäämällä tämän vektorin pisteeseen p1.
Huom! Sain idean myötäpäivään kääntämisestä kuvastasi. Toivottavasti olet varma, että se kuvaa jokaista ohjelmasi käsittelemää tilannetta oikein.
ISOT Kiitokset, AL! Pienen fiksailun jälkeen sain homman toimimaan tuon esimerkkisi kanssa juuri niinkuin pitää.
Tässä tulokset, jos jollekin on vaikka jotain apuja.
//Actionscript var startX:Number = 50; var startY:Number = 50; MovieClip.prototype.kurvi = function(endX, endY, force){ halfdist = Math.sqrt(Math.pow(endX-startX,2) + Math.pow(endY-startY,2))* .5; wX = ((endY - startY) / halfdist) * force + (( startX + endX ) * .5); wY = (((endX - startX) * -1) / halfdist) * force + (( startY + endY ) * .5); this.curveTo(wX,wY,endX,endY); startX = endX; startY = endY; } //Käyttö _root.kurvi(280,20,20);
Aihe on jo aika vanha, joten et voi enää vastata siihen.