[python] Vykreslování grafů

Karel Šrot karel.do.pekla.zajel na seznam.cz
Pátek Květen 25 09:30:38 CEST 2007


Jeste jsem si uvedomil, ze by vlastne bylo uplne nejlepsi kreslit ty 
grafy jako grafy parametricky zadanych funkci, coz by umoznilo kreslit i 
ruzne krivky. Ten vztah (f(a)-f(b))/(b-a)  by mohl byt
|[x(a),y(a)]-[x(b),y(b])|(b-a)...tedy v citateli je vzdalenost bodu, na 
ktere se zobrazi krajni body intervalu (pro parametr).

vzdalenost bodu [a1, b1], [a2, b2] je jak jiste vis 
sqrt((a2-a1)^2+(b2-b1)^2)

Karel


Karel Šrot napsal(a):
> Zdravim,
> 
> pocitat funkcni hodnoty a pak je spojit (lomenou) carou je naprosto 
> bezny zpusob. Treba Maple (progrma pro symbolicke vypocty) pocita 
> defaultne jen sto referencnich bodu. Pokud je v nejakem bode hodnota 
> nedefinovana (deleni nulou), Maple ji ignoruje (tedy bodu je pak min a 
> cara lomenejsi). Pomoci parametru lze specifikovat, zda se maji hledat 
> body nespojitosti. V tom pripade se pomoci "sofistikovanych" algoritmu 
> tyto body hledaji. Vcelku jednoduchou metodu Jan Jakubuv, ikdyz trochu 
> nepresne. To, ze je funkce nespojita jeste neznamena, ze ma limitu v 
> tomto bode rovnu nekonecnu.
> 
> Ja osobne bych tu moznost hledani bodu nespojitosti pouzil, tedy pokud 
> by uzivatel nic nezaskrtl, tak by se nehledaly a kresleni by bylo 
> rychlejsi.
> V opacnem pripade bych se smiril s pomalosti a pouzil bych pro hledani 
> bodu nespojitosti toto:
> Nejdrive si rozdelim cely interval na nekolik mensich, treba pomoci 200 
> (ci vice) referencnich bodu. Budu mit treba seznam [[0,1], [1,2], 
> [2,3],...]
> 
> Neni-li funkce v nejakem bode X definovana, je to bod nespojitosti. Do 
> seznamu ulozim hodnoty dva intervaly, pricemz pravy krajni bod prvniho 
> je X-E, a levy krajni bod druheho X+E, kde E je dostatecne mala hodnota, 
> ktera na grafu odpovida treba mene nez jednomu pixelu v grafu (to aby to 
> nebylo poznat).
> 
> Prochazim jednotlive intervaly a urcim tangens lomene cary, tedy 
> (f(a)-f(b))/(b-a). Pokud by byl tangens v absolutni hodnote vetsi nez 
> nejaka krajova zvolena hodnota (pro zacatek treba 5), bude interval 
> podezrely. Ulozim interval do seznamu podezrelych intervalu. Az mam 
> hotovo, prochazim kazdy podezrely interval.
> Rozdelim jej tedy napul a misto nej puvodniho mam ted dva intervaly. 
> Pocitam totez pro oba a ten, ktery je stale podezrely (hodnota tangens 
> bude v abs. hodnote jeste vetsi, nez byla predtim), budu zkoumat dal. 
> Ten, co uz podezrely neni, tak dam ze seznamu podezrelych pryc. Kdyz by 
> nahodou v polovine intervalu nebyla funkce spojita, pouziji to rozdeleni 
> na dva intervaly s tim S-E, S+E a ani jeden z intervalu neberu za 
> podezrely, protoze bod nespojitosti je mezi (tedy dam tyto intervaly 
> mezi nepodezrele a koncim). Podezrele intervaly muzu okrajovat znova a 
> znova, dokud hodnota tangens neprekroci nejakou danou mez. Pak 
> prohlasim, ze na intervalu je funkce nespojita a tento interval kreslit 
> nebudu. Protoze je strasne malej, tak to ani nebude vadit.
> 
> Az mi to bude stacit, tak pospojuji vsechny nepodezrele intervaly. Takze 
> seznam intervalu setridim, aby lezely za sebou. Pak je projdu odleva a 
> kdyz dva sousedni maji spolecny krajni bod, tak je nahradim jednim 
> velkym. Takze uplne nakonec budu mit seznam intervalu, kde je funkce 
> spojita. V mezerach mezi temito intervaly jsou body nespojitosti, ale 
> tyto mezery jsou male. Takze nakonec vykreslim gram funkce na kazdem z 
> techto intervalu.
> 
> Avsak kresneni nespojitych funkci je vzdy problem. Kdyz je funkce hodne 
> divoka (jde rychle do nekonecna), tak se muze stat, ze vam pretece 
> rozsah datoveho typu. Ale co se da delat.
> 
> Snad to bylo trochu jasne, zkus si to kdyztak projit s tuzkou, papirem a 
> grafem. Mnou uvedeny algoritmus bude potrebovat optimalizovat, protoze 
> se tam zbytecne moc manipuluje se seznamy a tak. Lze ho navrhnout lip, 
> ale ja zvolil tuto formu kvuli srozumitelnosti. Az ho pochopis, tak 
> jiste prijdes na to, ze se obejdes bez nadbytecneho vytvareni seznamu 
> itervalu.
> 
> No snad ti to pomuze, preci jen me to stalo trictvrte hodiny zivota. :-)
> 
> Karel
> 
> 
>> 2) Nevím jak vy byste vypočítávali body pro vykreslení grafu, ale já 
>> na to mám takovoutu metodu:
>>  
>> cislo=spodni_hranice
>> while cislo < horni_hranice:
>>        x=cislo
>>        y=eval(funkce.replace('x',cislo))
>>        body.append([x,y])
>>        cislo=cislo+preciznost
>>  
>> Ale výpočet se mi zdá poměrně dlouhý a tak se ptám jesetli vás 
>> nenapadá něco efektivnějšího. Dále jakou hodnotu by měla mít proměnná 
>> preciznost (nebo jestli by měl mít uživatel možnost ji nastavit).
>> 3) Nyní program dostává body jako souřadnice x,y a vykresluje 
>> jednotlivé pixely. Pochopitelně je to způsob relativně nepřehledný, 
>> protože pak může být na plátně jenom několik nic neříkajicích teček a 
>> proto by je chtělo nějak spojit. Napadlo mě spojit každé dva vedlejší 
>> body čárou ale pak mi došlo že to je nemožné, například kvůli grafu 
>> 1/cos(x).  Nevíte jaký způsob používají jiné programy?
>>  
>>  
>> Děkuji za případné odpovědi.
>>  
>> Jakub Vojáček.


Další informace o konferenci Python