Jednoduché geometrické výpočty
V tomto článku si ukážeme nějaké základní geometrické výpočty v rovině. Kdybyste je někdy potřebovali, tak si je jen okopírujete, anebo vás to může motivovat k psaní vlastních, pokročilejších funkcí :)
Začneme napsáním základních funkcí, které budeme využívat při psaní složitějších. Můžeme je dávat jako statické metody do třídy Geometry.
Vzdálenost dvou bodů
Vzdálenost dvou bodů (v prostoru s eukleidovskou metrikou) spočítáme Pythagorovou větou ($c = \sqrt{a\times a + b \times b}$).
Kód
public static function Distance(a:*, b:*):Number { return(Math.sqrt( (b.x-a.x)*(b.x-a.x) + (b.y-a.y)*(b.y-a.y) )); }
Zda bod leží v obdélníku
Obdélník mějme definovaný dvěma body: levým horním a pravým dolním rohem ("b" a "c"). Ptáme se, jestli bod "a" leží uvnitř obdélníku. a.x musí být mezi b.x a c.x, a.y musí být mezi b.y a c.y.
Kód
public static function isInRect(a:*, b:*, c:*):Boolean { if(a.x >= Math.min(b.x, c.x) && a.x <= Math.max(b.x, c.x) && a.y >= Math.min(b.y, c.y) && a.y <= Math.max(b.y, c.y)) return true; return false; }
Průsečík dvou úseček / přímek
Mějme úsečky "a", "b" definované dvěma body (začátky "a1", "b1" a konce "a2", "b2"). Chceme zjistit bod, kde se protínají. Nejdřív najdeme průsečík přímek a, b. Aby to byl průsečík úseček, musí ležet mezi začátky a konci obou úseček.
Při výpočtu průsečíku si přímku převedeme do směrnicového tvaru $y = f\times x + g$, kde "f" je směrnice a "g" je svislý posun.
Kód
public static function GetLineIntersection(a1:*, a2:*, b1:*, b2:*):Point { var f1:Number = -(a2.y - a1.y) / (a1.x - a2.x); var f2:Number = -(b2.y - b1.y) / (b1.x - b2.x); var g1:Number = a1.y - f1 * a1.x; var g2:Number = b1.y - f2 * b1.x; // rovnoběžky -> žádný průsečík if(f1 == f2) return null; var inter:Point; if (a1.x == a2.x) inter = new Point(a1.x, f2*a1.x + g2); else if (b1.x == b2.x) inter = new Point(b1.x, f1*b1.x + g1); else { inter = new Point((g2-g1)/(f1 -f2),0); inter.y = f1 * inter.x + g1; } if(isInRect(inter, a1, a2) && isInRect(inter, b1, b2)) return inter; return null; }
Střed kružnice opsané
Mějme tři body v rovině (a, b, c). Hledáme kružnici (její střed a poloměr), která prochází těmito třemi body. Tj. hledáme bod (střed kružnice), který má stejnou vzdálenost od a, b, c. Uděláme si osu úsečky a,b (to jsou body se stejnou vzdáleností k "a" a "b"), osu úsečky b,c (body stejně vzdáleny od b, c) a průsečík těchto os je stejně vzdálen od a, b, c.
Kód
public static function GetCircumcenter(a:*, b:*, c:*):Point { // m1 - bod uprostřed (a,b), osa ním prochází var f1 = (b.x - a.x) / (a.y - b.y); var m1 = new Point((a.x + b.x)/2, (a.y + b.y)/2); var g1 = m1.y - f1*m1.x; var f2 = (c.x - b.x) / (b.y - c.y); var m2 = new Point((b.x + c.x)/2, (b.y + c.y)/2); var g2 = m2.y - f2*m2.x; // ošetření degenerovaných případů // - tři body na přímce if (f1 == f2) return null; // - a, b ve stejné výšce -> směrnice osy |ab| = nekonečno else if(a.y == b.y) return new Point(m1.x, f2*m1.x + g2); else if(b.y == c.y) return new Point(m2.x, f1*m2.x + g1); var x:Number = (g2-g1) / (f1 - f2); return new Point(x, f1*x + g1); }
Vyborne spracovanie. Videl som uz rozne ukazky geometrie ale toto je najlepsie.
Chysta sa aj pokracovanie?
Chybka? Ked sa pohybuje lavym-hornym bodom tej cervenej kruznice pomaly hore a dolu tak tam preblikavaju ciary veduce k lavemu hornemu okraju plochy Flash plazera... Je to takto OK?
Tak jo,, vyzera to na delenie nulou pri vypocte:
var f1 = (b.x - a.x) / (a.y - b.y);
a f2.
Ahoj, dobrý postřeh! :) Mohou nastat degenerované stavy (osa přímky svislá -> směrnice nekonečno, s tím nejde moc počítat). Už jsem to opravil.
Máte zájem o nějaké konkrétní pokračování?
Convex hull, test bodu v polygone s lubovolnym tvarom, curve fitting - kreslenie ciary rukou a jej nasledne zjednodusenie, cosi uz je hotove - http://www.flashandmath.com/devarticles/index.html.
Tak, sorry - http://active.tutsplus.com/tutorials/actionscript/euclidean-vectors-in-flash/ - bod v polygone
Pri teste prisesecnikov ciar - BUG?
http://img823.imageshack.us/i/priesecnikyciar.png/
Uvital by som upravene verzie AS3.0. Diky.
No a snad posledny BUG...
http://img594.imageshack.us/i/opisanakruznica.png/
Díky za připomínky. Jedná se o stejné degenerované případy - svislé čáry a rovnoběžky. Opravil jsem to.
Este ta kruznica - http://img7.imageshack.us/i/kruznicabodynajednejpri.png/ ked su body v rovine ALEBO na jednej priamke.
Bude aj AS3.0 k dispozicii?
Kód je teď v AS3.0 (možná splňuje i AS2). Kružnice je podle mě správně. Jen to flash blbě vykresluje (občas mu dělá problémy, když má kreslit na "velké souřadnice").
Super stránky.
Velmi pěkně napsané :) . Ale když jsem koukal na tvůj výpočet průsečíků dvou přímek, tak jak řešíš pokud bod a1x a2x leží v rovině? Nevím jaký je to jazyk, zde totiž může nastat dělení nulou. Pak nebude dávat zbytek výpočtu smysl.