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.
_______________________________________________
Python mailing list
python@py.cz
http://www.py.cz/mailman/listinfo/python

Visit: http://www.py.cz

Odpovedet emailem