Autor Zpráva
peta
Profil
Potreboval bych otocit pozice 1-8 objektu do 3d bez canvas. Jedna se o rozmisteni figurek. Muzu to udelat rucne nebo pouzit rovnice. Nevedel by jste nekdo rovnice?

function createPositions()
{
var arr, size, angle,i,j, a,b;
boardsize  = [100,100];
unitsize   = [17,15];
angle = [-30,-30];
// poloha jednotek 2D [%]
arr   = [
[[50,50]],
[[50,33],[50,66]],
[[50,33],[33,66],[66,66]],
[[33,33],[66,33],[33,66],[66,66]],
[[33,25],[66,25],[50,50],[33,75],[66,75]],
[[25,33],[50,33],[75,33],[25,66],[50,66],[75,66]],
[[25,25],[50,25],[75,25],[50,50],[25,75],[50,75],[75,75]],
[[25,25],[50,25],[75,25],[37.5,50],[62.5,50],[25,75],[50,75],[75,75]],
];

// poloha jednotek 3D [px]
for (i=0;i<arr.length;i++)
    {
    for (j=0;j<arr[i].length;j++)
        {
        a = arr[i][j][0];
        b = arr[i][j][1];
        // 2D
        a = a/100 * boardsize[0] - unitsize[0]/2;
        b = b/100 * boardsize[1] - unitsize[0]/2;
        // 3D
// tady treba dosadit rovnice pro otoceni
//        a = a/100 * boardsize[0] - unitsize[0]/2;
//        b = b/100 * boardsize[1] - unitsize[0]/2;
        arr[i][j][0] = a;
        arr[i][j][1] = b;
        }
    }
return arr;
}
_es
Profil
peta:
Nevedel by jste nekdo rovnice?
Vyhľadávače, trebárs tebou obľúbený Google, snáď nefungujú? http://cs.wikibooks.org/wiki/Geometrie/Prom%C3%ADt%C3%A1n%C3%AD
peta
Profil
No, az na to, ze ani jedna ukazka nepocita to, co ja potrebuji. Takovych se mnasel mraky, 200 stranek.
A pak je tu takova vyznamna drobnost, funkcni example, kde zadas vstupni hodnoty a vyplivne vystupni.

Prvni ukazky jsou jakesi silene maticove pocty zapsane v C#. Coz nema s JS nic spolecne, ze jo?
Středové promítání - to vychazi z toho, ze znam souradnice x,y,z, ktere ja prave ale neznam. Ja znam vysledky te funkce na wiki. a tez je to v C#.

Tvou odpoved tedy povazuji spis o pokus o vtip.
1Pupik1989
Profil
Pro otočení do 3D je potřeba i poloha na Z, ne? Nebo počítáš s tím, že Z = 0 a je to bez perspektivy?

Matice je jasná.



Při čemž toto je otočení dle osy Z.


Přinejhorším je to rozepsané ZDE.
juriad
Profil
ty šílené maticové počty přesně odpovídají transformaci, kterou chceš provést; mají pěkné algebraické vlastnosti, tedy nemusíš se zabývat jednotlivými "rovnicemi"

nevím, co přesně myslíš těmi úhly, proto situaci trochu zjednoduším:
máš svislou desku, která splývá s průmětnou (obrazovkou), na této desce jsou zadané body
ty je chceš vykreslit tak, jakoby ta deska byla poklopená o 30 stupňů dozadu podle vodorovné osy (spodní části obrazovky)

1/ vymyslíš matici rotace podél přímky o zadaný úhel
2/ touto maticí vynásobíš každý bod (bod má 3 souřadnice (x, y, 0)), tím získáš bod v prostoru
3/ následně sestavíš matici projekce (takové, o kterou máš zájem)
4/ maticí projekce vynásobíš bod v prostoru, tím bod promítneš do obrazovky (projekce třetí složku opět vynuluje)

PS: tvrdíš o sobě, že C# umíš, tady problém být nemůže
_es
Profil
peta:
Středové promítání - to vychazi z toho, ze znam souradnice x,y,z, ktere ja prave ale neznam.
No tak keď ich nemáš, tak to nemáš ako otočiť. 2D zobrazenie 3D objektu nemáš ako otočiť v 3D priestore a potom zase premietnuť do 2D zobrazenia - to je snáď jasné.
peta
Profil
Nakonec jsem tam doplnil jen otoceni. Dost mne potrapilo reseni kvadrantu pro tangent :) Nejdriv jsem to chtel osidit jednoduchou formulkou, ale pote jsem zjistil, ze mi to pocita spatne, tak jsem tam dal uplny zapis.
        x = arr[i][j][0];
        y = arr[i][j][1];
        // 2D
        x = x/100 * w - (imgsize.w>>1);
        y = y/100 * h - (imgsize.h>>1);
        // 3D
        x0 = x - (w>>1) //center point
        y0 = y - (h>>1)
        r  = Math.sqrt(x0*x0 + y0*y0);            // radius (distance)
        a  = Math.atan(y0/x0)
        a  = y0>0 ? (x0<0 ? Math.PI + a : a) : (x0<0 ? Math.PI + a : 2*Math.PI + a);    // angle qadrant
        //a  = a<0 ? 2*Math.PI + a : a;    // angle near zero
        a += 0.5;
        x  = r * Math.cos(a); 
        y  = r * Math.sin(a);
        x *= 0.75;
        y *= 0.75;
        x  = x + (w>>1);
        y  = y + (h>>1);
        arr[i][j][0] = Math.floor(x);
        arr[i][j][1] = Math.floor(y);
1Pupik1989
Profil
Podle mě by bylo mnohem snažší přidat osu z.
peta
Profil
Jeste drobnou korekci
x = x + (w>>1);
y = y + (h>>1);
x *= 0.75;

1Pupik1989:
Dyt jsem se na reseni v javascriptu ptal a nedostal jsem rozumnou odpoved, kousek kodu. Jen odkazy na matematickou teorii. Kdyby mi bylo 12, tak se v te hatmatilce nevyznam. At si to napisi matematici srozumitelne, cesky nez to zacnou prezentovat.
1Pupik1989
Profil
Tak znova. Rotace na Y:

function rotateY(p, deg)
{
  var deg = deg * Math.PI/180;
  return [
    (p[0] * Math.cos(deg)) - (p[2] * Math.sin(deg)),
    p[1],
    (p[0] * Math.sin(deg)) + (p[2] * Math.cos(deg)),
  ];
};;

Je obrázek, který má souřadnice x,y,z.
x je třeba 10, y 20 a z -100.
Takže pole bude vypadata následovně:
[10,20,-100]
Pojmenujme pole třeba coords
Teď přesně víš, kde se v prostoru nachází. Ty chceš ten objekt natočit o, dejme tomu, 45 stupňů.
Zavoláš funkci rotateY s prvním parametrem souřadnic a druhý bude úhel.
Čili:
rotateY(coords,45)
Ta ti vrátí body x,y,z jenže už otočené. Teď si všimni prvního řádku v poli co vrací ta funkce. Počítá se tam kosínus a sínus. No a teď mrkneme na matici rotace pro osu Y, co jsem poslal.



Určitě je jasný, že pro rotaci na ose Y slouží ta prostřední Ry

Vidíš tu podobnost? Hned první řádek je kosínus, pak 0, pak sínus.

Je to v podstatě hodně jednoduché, jen jde o to počáteční pochopení. Maticím pro rotace se prostě nevyhneš. Nejlepší příklad pro rotace je asi Koule v HTML 5 canvasu. Nehleď na to, že je to v canvasu, ty potřebuješ hlavně ty rotace a projekci.

Doufám, že jsem to vysvětlil nějak polopaticky. Vlastně řádky v matici jsou právě ty body, které potřebuješ x,y,z.

Snad podle toho příklad už doděláš rotace i na zbylé osy. :)

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:

0