Autor Zpráva
KryVosa
Profil
Ahoj, lidi :) Rozhodl jsem se znovu a neobratně vymýšlet trakař, totiž javascriptový framework pro vektorové animace. Mám tady jakýsi "základ", totiž funkci Vector.
Můj dotaz: Jak se počítají Bézierova kubická a kvadratická křivka, a jak je následně přenést do X a Y pro pohyb. A to jednodušší: Pokuste se mě nakopnout, jak udělat pohyb po kružnici :)
Tady je kód. Zátěžové testy dopadly dobře, rychlost animace se nemění ani při 50 animovaných elementech. Víc jsem nezkoušel :)
Máte-li návrhy na optimalizaci kódu nebo přidání užitečných funkcí, taky je napište.
Všem vám předem děkuju.
Martin2
Profil *
KryVosa:
Jak se počítají Bézierova kubická a kvadratická křivka
Google už zase nefunguje? Už na první výsledkové stránce najdeš tolik vysokoškolských skript, že tě přejde legrace.

Rozhodl jsem se znovu a neobratně vymýšlet trakař, totiž javascriptový framework pro vektorové animace
Asi nemá smysl upozorňovat, že trakaře už existují - a dost kvalitní, dost odladěné.
KryVosa
Profil
Martin2:
Google už zase nefunguje? Už na první výsledkové stránce najdeš tolik vysokoškolských skript, že tě přejde legrace.
Právě že najdu. Ale z těch se těžko chápe. Proto jsem tady... Samozřejmě, že googlovat jsem zkoušel :)

Asi nemá smysl upozorňovat, že trakaře už existují - a dost kvalitní, dost odladěné.
Jak napsal tuším Chammurapi: "Nebojte se vymýšlet kolo znovu a znovu, vylepšíte tím své schopnosti. A možná ho uděláte kulatější." Kvůli nejen tomu si tu s tím hraju :)
Alphard
Profil
stackoverflow.com/a/16227479

a jak je následně přenést do X a Y pro pohyb
Nechápu, křivku získáte jako množinu bodů, každý z ních má souřadnici X a Y.

Pokuste se mě nakopnout, jak udělat pohyb po kružnici
Co třeba v cyklu vypočítávat body z parametrické rovnice kružnice?
Martin2
Profil *
KryVosa:
Právě že najdu. Ale z těch se těžko chápe.
S tím nic nenaděláš. Parametrické křivky jsou vysokoškolská matematika. Pokud tomu chceš rozumět, ne jen kopírovat bloky kódů, tak se bez určitých znalostí neobejdeš.
KryVosa
Profil
Alphard: Promiň, byl jsem ještě pořád ve světě, kde si musíš pomocí sin a cos dopočítávat x a y :) To druhé není špatný nápad... Zkusím to :)
Martin2: Kusu kódu ale zatím rozumím lépe, než neprobrané matematice, takže mě to nakopne mnohem víc :)
Alphard
Profil
KryVosa:
Promiň, byl jsem ještě pořád ve světě, kde si musíš pomocí sin a cos dopočítávat x a y
Já sám jsem nebyl úplně přesný, vzhledem k předchozímu jsem napsal v podstatě to nejpřímočařejší řešení. Obecně bod samozřejmě nemusí mít zrovna X a Y souřadnici, můžeme ho reprezentovat např. v polární soustavě a pak by byl popsaný převod nezbytný.

Kdybych něco takového psal v C++, určitě bych si pro reprezentaci bodu v prostoru vytvořil nový typ, např. Point, abych ve vyšší vrstvě nemusel tyhle věci vůbec řešit:
Point p1(x1, y1);
Point p2(x2, y2);
Point c = 3 * (p1 - p2);
// ...
Line line(c, d);
canvas.drawLine(line);
V javascriptu nevím, jak by se to projevilo na výkonu.
KryVosa
Profil
Alphard:
Asi by to nebyl špatný nápad. Akorát nevím o žádné možnosti odčítání dvou vlastností objektu najednou podobným zápisem... Už by se na to musela udělat funkce a hromada dalších věcí. Na výkonu ale v téhle fázi tolik nezáleží, celá křivka by se předpočítala před animací. Žádná z těch čar se stejně kreslit nebude :)
Délku celé křivky si musím spočítat z vzdáleností jednotlivých bodů, nebo na to existuje nějaká zázračná rovnice?
Pochopil jsem z kódu správně, že když položím body p2 a p3 na stejné místo, vznikne mi "obyčejná" kvadratická Bézierova křivka?
V případě, počet opakování smyčky "upřesňování" křivky bude jedna, bude z toho nakonec přímka?

Díky, potřeboval jsem to nějak smrsknout, snažím se to poskládat a přivést k životu...
Edit: Jestli bude potřeba dopočítat délku křivky, tak se sin a cos stejně nevyhnu :)
Alphard
Profil
KryVosa:
Akorát nevím o žádné možnosti odčítání dvou vlastností objektu najednou podobným zápisem...
Javascript bohužel neumí uživatelsky přetěžovat operátory.

Délku celé křivky si musím spočítat z vzdáleností jednotlivých bodů, nebo na to existuje nějaká zázračná rovnice?
Ano, déku lze spočítat s využitím různých aproximací. Teď jsem zkoušel nějaká řešení hledat a čím výpočetně efektivnější metoda, tím složitější matematika. Stačí hledat...

V případě, počet opakování smyčky "upřesňování" křivky bude jedna, bude z toho nakonec přímka?
Nerozumím, jde o tohle?
for (var i=0; i<1; i+=accuracy){
   var p = bezier(i, p0, p1, p2, p3);
   ctx.lineTo(p.x, p.y);
}
Při první iteraci se (trochu zbytečně) vypočítá počáteční bod (který je známý), takže k dosažení přímky je třeba ještě druhá iterace.
KryVosa
Profil
No. Přidělal jsem si do new VectorCurve() něco jako accuracy, která určuje přesnost křivky. Celou křivku jsem si "nahrál" do pole, spočítal její délku a pak akorát přes nějaký "index" obnovoval... Navíc to dovoluje udělat několik křivek za sebou, navázaných, což je nesporná výhoda :)

Děkuju všem, hned jak dodělám první experimentální verzi zbytku vektorových pohybů, tak jí sem postnu :)
KryVosa
Profil
Pokusil jsem se "přepsat" obecnou matematickou funkci pro Bézierovu křivku n-tého stupně, ale nějak se mi to nepovedlo... Funguje do dvou bodů... Jde dělám chybu? Díky :)
function expCurve(t,points)
      {
      var x=0;
      var y=0;
      for(var i=0;i<=points.length-1;i++)
      {
        x+=Math.combination(points.length-1,i)*Math.pow(t, i)*Math.pow((1-t),(1-i))*points[i].x;
        y+=Math.combination(points.length-1,i)*Math.pow(t, i)*Math.pow((1-t),(1-i))*points[i].y;
      }
      console.log(x+"/"+y)
      return {x:x,y:y}
      }
V případě, že dodám třetí bod,, místo křivky mi x i y stále roste (podle velikost points[2].x a points[2].x)

Edit: Pochopil jsem správně, že se ta křivka tvoří nějak takto?: Vezme se t* vdálenost bodu p0 a p1 (p01), t* vzdálenost p1 a p2 (p12). Pak se vezme t* vzdálenost bodů p01 a p12, a to je jeden bod křivky?
Alphard
Profil
KryVosa:
x+=Math.combination(points.length-1,i)*Math.pow(t, i)*Math.pow((1-t),(1-i))*points[i].x;
Tohle půjde pro vyšší stupně do záporných čísel. To vypadá hodně podezřele.
KryVosa
Profil
Díky, nevšiml jsem si toho ani po padesátém čtení. Teď už funguje bez problémů. Přidělávám funkce addPoint, removePoint, changePoint, addCurve, reverse.
KryVosa
Profil
První drobná maličkost, kterou jsem vytvořil svým frameworkem: Odkaz

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: