Parabola   otázka

C#, Algoritmy, Grafika

Dobrý den,

chtěl bych se zeptat na postup, jak namalovat parabolu. Jak vytvořit graf vím, ale nějak mi nejde do hlavy, jak nakreslit tu parabolu, z rovnice:

ax^2+by+c=0

Děkuji

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Oprava:

ax^2+bx+c=0

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Vzdálenost souřadnice Ay bodu A[Ax;Ay] od osy x ježícího na parabole je dána rovnicí y=a*x^2+b*x+c. Způsob, jakým vynést graf paraboly by tedy mohl vypadat nějak takto:

Dim b = New Bitmap(400,400)
Dim g = Graphics.FromImage(b)
g.TranslateTransform(200,200) ' umístíme nulu souřadnicové systému doprostřed obrázku
Dim y As Integer
Dim a,b,c As Double ' dosadíte si řídící proměnné paraboly
For x=-200 To 200
    y=a*x^2+b*x+c
    g.DrawRectangle(Brushes.Black,x,y,1,1)
Next

Samozřejmě možností je více.

1.) Lepší, než kreslení pixelů by bylo kreslit rovnou křivku z daných bodů, vypadalo by to lépe díky antialiasingu.

Algoritmus pro tento postup by byl:

V každém kroku cyklu, pokud

a) uložení bod neexistuje, nakreslit pixel

b) uložený bod existuje, nakreslit čáru od uloženého bodu do současných koordinátů a uložený bod nahradit aktuálním bodem

2.) Ještě lepší by pak bylo mít sadu bodů a tu předat do DrawCurve.

3.) Nejlepší jak z hlediska objemu kódu, tak z hlediska výpočetní náročnosti by bylo aproximovat parabolu pomocí kruhové (resp. elipsové) výseče, pokud je graf pouze informační a jde opravdu pouze o graf - nebudete používat parabolu pro další výpočty. Zkrátka pokud si můžete dovolit nepřesnosti. Jak zjistit rozměry paraboly byste měl být schopen vydedukovat, pokud si o parabole něco přečtete. Na wikipedii je hezky zpracovaný jak český, tak anglický článek.

Kód ve ve Visual Basic .NET, bude třeba si jej převést do C#.

Zdroje:

http://cs.wikipedia.org/wiki/Parabola_%2...

http://en.wikipedia.org/wiki/Parabola

http://www.codeproject.com/Articles/3278...

EDIT: Trochu jsem si s tím hrál a tady je výsledek. Vytvořil jsem Extension metodu, která přebere jako parametr bitmapu, pero a parametry paraboly a vykreslí ji pomocí DrawCurve:

    <System.Runtime.CompilerServices.Extension()> _
    Public Sub PlotParabola(bitmap As Bitmap, pen As Pen, a As Double, b As Double, c As Double)
        Using canvas = Graphics.FromImage(bitmap)
            canvas.TranslateTransform(bitmap.Width / 2, bitmap.Height / 2)
            canvas.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
            With canvas.VisibleClipBounds
                canvas.DrawCurve(pen, Enumerable.Range(.Left, .Width).Select(Function(x) New PointF(x, a * (x ^ 2) + b * x + c)).ToArray())
            End With
        End Using
    End Sub

Použití je zřejmé:

        Dim b As New Bitmap(400, 400)
        b.PlotParabola(Pens.Blue, 0.1, 2, 0)
        b.PlotParabola(Pens.Maroon, 0.2, 2, 10)
        b.PlotParabola(Pens.Green, 0.3, 2, 20)
        b.PlotParabola(Pens.Yellow, 0.4, 2, 30)
        PictureBox1.Image = b

Opět platí, že veškerý kód je ve VB .NET.

Ovšem je důležité podotknout, že by bylo lepší udělat to jako Extension metodu k objektu Graphics. Musíte mít na paměti, že v takovém případě by transformace buď odpadla úplně (resp. transformovat byste to musel mimo tělo metody) a nebo byste to transformoval jako to dělám já, ale u konce metody byste transformoval zase zpět! Jinak by se stalo to, že po každém zavolání metody by Vám střed odjížděl.

Jak vidíte, metoda je rychlá, protože iteruje pouze potřebnou oblast osy x (viditelné souřadnice zleva až do prava, ne celý objekt Graphics), pokud budete chtít, můžete také přidat podmínku, která zajistí, že se použijí pouze hodnoty x, které budou vracet viditelné výsledky na ose y. Opět je nasnadě studium rovnice paraboly a základní porozumění kuželosečkám.

A ještě jedna poznámka nakonec: transformace, kterou provádím já pouze posune střed vykreslování do viditelného regionu grafiky. Správná transformace by ale měla být taková, která převrátí y osu (protože na monitoru y stoupá směrem dolů, v grafech ale stoupá směrem vzhůru) a posune do středu pouze po x, y by se mělo posunout odspodu na nějakou rozumnější hodnotu, například vzdálenost paty paraboly od řídící přímky, což je polovina vzdálenosti ohniska (velikost parametru).

nahlásit spamnahlásit spam 2 / 2 odpovědětodpovědět

Děkuji za vyčerpávající odpověď :-)

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback