czy ktos poradzilby co zmienic w ponizszych wzorach, zeby punkt stawial sie poprawnie
obrot wokol osi x:
z1=cos(kat)*y-sin(kat)*z;
y1=sin(kat)*y+cos(kat)*z;
x1=x;
k=wspolczynik powiekszenia;
plot (x1/z1*k, y1/z1*k);
Nie jesteś zalogowany. Proszę się zalogować lub zarejestrować.
Nowa obudowa dla 800XL - zostało 36 dni Niewiele ponad miesiąc do końca kampanii.
Zmarł twórca języka BASIC Zmarł Thomas E. Kurtz twórca języka BASIC
Zmiana serwera atari.area Serwis przeszedł właśnie ważną aktualizację infrastruktury
4th Atari ASCII Compo - wyniki Dostępne są już wyniki tegorocznego ATASCII Compo.
thing neo 1.60 Olivier Landemarre wydał nową wersję desktopu Thing.
atari.area forum » Programowanie - 8 bit » stawianie punktu w 3d
Zaloguj się lub zarejestruj by napisać odpowiedź
czy ktos poradzilby co zmienic w ponizszych wzorach, zeby punkt stawial sie poprawnie
obrot wokol osi x:
z1=cos(kat)*y-sin(kat)*z;
y1=sin(kat)*y+cos(kat)*z;
x1=x;
k=wspolczynik powiekszenia;
plot (x1/z1*k, y1/z1*k);
na pc uzywalo sie notacji maciezowej chocby ze wzgledow praktycznych - po wymnozeniu 3 rotacji skladowych dostajesz wynik ktory ma 9 mnozen, a mnozac osobno masz ich 12
rotajce masz ok, perspektywe...
x1*k/z1, y1*k/z1, pod warunkiem ze z jest skierowana w glab ekranu
nie wiem co jest grane,niby stosuje te wzory a punkty sie dziwnie rozjezdzaja :( zarzucam kod w C,moze ktos
sie dopatrzy bledu:
static double xt[200]={0};
static double yt[200]={0};
static double zt[200]={0};
static int index=0;
void kolo(int y,int z,int color,bool a){
for (double kat=0; kat<10;kat+=0.3)
{
xx=40;
zz=(cos(kat)*y-sin(kat)*z);
yy=(sin(kat)*y+cos(kat)*z);
if(a){xt[index]=xx;yt[index]=yy;zt[index]=zz;index++;}
};}
int main()
{
double stx=320,sty=240;
double k=3;
double y=40,z=-40;
kolo(y,z,0x00ff00,true);
for (int t=0;t<index;t++)
plot(xt[t]/zt[t]*k+stx,yt[t]/zt[t]*k+sty,0x0fffff);
return 0;
};
Jakby ktos pytal to jest kod atari przelozony na kod pc.
pracuj caly czas na floatach, ostatnie rzutowanie zrob na integer z zakresu, jesli bedzie ok to masz problem z precyzja
1) Funkcje sin(), cos() przyjmują argumenty w radianach. Przyrosty kątowe 0.3 mogą być zbyt duże i dawać wrażenie chaotyczności.
2) Wsp. k powinien być pochodną rozmiarów okna obrazu oraz perspektywy. Tymczasowo powinieneś go zwiększyć.
3) Będą działy się różne paskudne rzeczy, jeżeli nie wykluczysz dzielenia przez 0, które jak najbardziej jest możliwe w tej sytuacji. Proponuję dodać odpowiednio duży offset do zz.
Sprobowalem i z floatami i z offsetem do zz i nadal to samo:
(obrot kola wokol osi y)
obrot wokol osi x:
z1=cos(kat)*y-sin(kat)*z;
y1=sin(kat)*y+cos(kat)*z;
x1=x;
Powinno być:
z1=cos(kat)*z-sin(kat)*y;
y1=sin(kat)*z+cos(kat)*y;
x1=x;
ewentualnie odwrotnie znaki przy sinach - będzie obrót w drugą stronę.
Najpierw mnóż przez k, a potem dziel przez zt[t] - wtedy xt[t] i zt[t] będą mogły być całkowite.
zt[t] powinny być dodatnie - tj. punkty są za ekranem, a nie przed. Możesz dodać przesunięcie po wykonaniu obrotu.
Sprobowalem i z floatami i z offsetem do zz i nadal to samo:
(obrot kola wokol osi y)
http://img35.imageshack.us/img35/7440/wekt.png
Jeżeli pod pojęciem rozjeżdzania masz na myśli rosnące przerwy między punktami wzdłuż osi X, to wszystko jest w porządku. To skutek zaaplikowania perspektywy.
Ustaw offset z'ta na 150, a k na 554. Perspektywa będzie mniej "agresywna".
http://codebase64.org/doku.php?id=base:3d_rotation
A czy te przerwy, to nie jest problem, że oś x i y nie są w tej samej fizycznej skali ?
tego mi trzeba bylo,teraz punkt stawia sie poprawnie.Do perspektywy uzylem wzorow:
Focal=ogniskowa;
rzut=Focal/(z+Focal);
x1=x*rzut+srodek ekranuW;
y1=y*rzut+srodek ekranuH;
Swoja droga to ciekawe,ze jest kilka rodzajow wzorow na obroty i kilka na rzut perspektywiczny.
Jeszcze odnosnie obrotow:zastanawiam sie jak zrobic,zeby punkty obracaly sie nie wokol srodka ukladu wspolrzednych ale wokol dowolnej osi w przestrzeni,dysponuje ktos moze stosownym linkiem odnosnie tego problemu?
potrzebujesz cos co sie nazywa lokalny uklad wspolrzednych
czyli rotacja obiektu wedle lokalnego ukladu wspolrzednych, translacja do jego polozenia w globalnym ukladzie wspolrzednych i znow rotacja globalnego ukladu wspolrzednych
krocej - brakuje ci kamery ;)
to ja jeszcze w sprawie kamery...
do przeksztalcen wspolrzednych swiata do wspolrzednych kamery sprobowalem zastosowac ta macierz(na samym dole stronki) ale zamiast np. przesuniecia kamery wzdloz osi x program obraca mi punkty wokol poczatku ukladu wspolrzednych swiata, tak jakby tam stala kamera. Moze znalazby sie ktos obeznany z tematem i udzielil rady jak krok po kroku stworzyc tak`ową kamere?
no ale na dole masz iloczyn skalarny tego gdzie sie znajduje kamera (punkt s), wektorki p g k to uklad ortonormalny kamery (uklad loklany)
wiec jak ty masz tam same 1 to co ma sie stac?
jesli chcesz moge wyslac engine ale w asmie x86
niby wszystko podstawiam dobrze pod wzor...najpierw licze sobie wektory,co by byly prostopadle do siebie,normalizuje,potem okreslam przesuniecie kamery,podstawiam to wszystko do macierzy i nic.
za engine dzieki,ale nie rozczytam.
odświeżam temat: po dłuższym czasie wróciłem do tematu, kamera działa, obraca się , problem tylko z kolejnością obrotów, jak najpierw obracam wokół osi Z kamery to osie X i Y dziwnie się zachowują (obracają się względem osi X i Y świata) gdy robie odwrotnie to obrót Z zamiast kręcić się wokół punktu w środku widoku kamery obraca się względem osi Z świata.
Czy któryś z szanownych kolegów programistów wie czym może być to spowodowane?
pozdrawiam,
Gorgh
Przesuń najpierw świat, tak, aby kamera była w (0, 0, 0).
kamera jest w 0,0,0 bo najpierw obracam wektory kamery a potem podstawiam je do macierzy kamery (obrotu i translacji) przez którą mnożę wszystkie wierzchołki. Albo coś pokićkałem, albo coś jest nie tak z tymi obrotami i trza użyć czegoś bardziej skomplikowanego, w razie czego dołączam filmik pokazujący co jest nie tak (WMPlayer),
pozdrawiam z pola bitwy,
gorgh
Może spróbuj skrótowo opisać algorytm jakiego faktycznie używasz: Opisz jak przeliczasz każdy z wejściowych puntków (x,y,z), aby otrzymać końcową pozycję na ekranie (przez co mnożysz, jakim wzorem, punkt po punkcie) bo rozłożenie punktów jest tak nierównomierne, że mi to wygląda na błąd w zastosowanej formule.
Może spróbuj skrótowo opisać algorytm jakiego faktycznie używasz: Opisz jak przeliczasz każdy z wejściowych puntków (x,y,z), aby otrzymać końcową pozycję na ekranie (przez co mnożysz, jakim wzorem, punkt po punkcie) bo rozłożenie punktów jest tak nierównomierne, że mi to wygląda na błąd w zastosowanej formule.
Załączam kod w Javie z komentarzami, który wysłałem do jednego z koderów z którym również koresponduje w tej sprawie (mam nadzieje, że się nie obrazi) :
// początkowe wartości wektorów kamery- up, front, right, wektory
jednostkowe
//(camz,camx,camy to obiekty klasy wektor z polem float x[4]);
camz.x[0]=0;camz.x[1]=0;camz.x[2]=1.0f;camz.x[3]=1;
camx.x[0]=1.0f;camx.x[1]=0;camx.x[2]=0;camx.x[3]=1;
camy.x[0]=0;camy.x[1]=1.0f;camy.x[2]=0;camy.x[3]=1;
// obroty na poszczegolnych osiach 3 wektorow kamery ,wartosci obrotow
wziete z wejscia
// oś y obraca wokoł osi Z kamery, jakoś tak mi się poprzestawiało, w
kazdym badz razie
//najpierw obracam osie x i y a na koncu z- wynikiem jest bledne obracanie
wokol osi Z
// gdy obrot jest najpierw wokol osi Z blad dotyczy pozostalych dwóch osi
obrocx(camz,osx*3.14f/180);
obrocx(camx,osx*3.14f/180);
obrocx(camy,osx*3.14f/180);
obrocz(camz,osz*3.14f/180);
obrocz(camx,osz*3.14f/180);
obrocz(camy,osz*3.14f/180);
obrocy(camz,osy*3.14f/180);
obrocy(camx,osy*3.14f/180);
obrocy(camy,osy*3.14f/180);
// przygotowanie macierzy (wstawienie 1.0 w kilka pól)
mtxbase(mbase);
//normalizowanie wektorów (na wszelki wypadek)
wersor(camz);
wersor(camx);
wersor(camy);
// ustalanie pozycji kamery
campoz.x[0]=pozx;campoz.x[1]=pozy;campoz.x[2]=pozz;campoz.x[3]=1;
//przygotowanie macierzy projekcji-wszystkie punkty świata mnożone są
przez tą macierz
//campoz służy do translacji, pozostałe wektory, jako normalne służą
do ustalenia obrotu
// poszczególne pola macierzy :plik JPG w załączniku
makeview(mbase,camx,camy,camz,campoz);
[edit] W załączonej macierzy brakuje translacji (pola 3,7,11)
[edit 2] punkty są rzucone na chybił trafił, to raczej nie wiąże się z samym problemem
Twoje podejście jest odrobinę "niekanoniczne". A jak robi się coś niestandardowo, to łatwiej o błędy. Ja stosuję się do metody używanej w direct3d i jedyne problemy jakie miewam, to czy transponować ostateczną macierz, czy nie (bo zwykle nie pamiętam jak ostatecznie ma być).
Jedyne co mogę zaproponować, to:
1. Porzuć tę metodę, którą teraz używasz, bo taniej jest napisać to dobrze od nowa, niż szukać błędu.
2. Przeczytaj w tutorialu z dokumentacji do direct3d 9: Transforms oraz podstrony World, View oraz Projection. Dowiedz się też, co to jest Viewing Frustum.
3. Znajdź / napisz klasę macierzy oraz funkcje tworzenia osobnych macierzy do rotacji w każdej z osi, translacji, skalowania i perspektywy oraz metodę mnożenia macierzy przez siebie i mnożenia wektora przez macierz tak, jak jest to w tym tutorialu.
4. Twórz macierze, mnóż i voilà (ewentualnie przetransponuj końcową macierz jak nie wyjdzie ;)).
Ciężko będzie pomóc, bo pokazałeś tylko wycinek kodu. Pozostaje zgadywać: np. czy odrzucasz punkty niewidoczne w kamerze?
@Fox:załączam całość źródeł, nie jest tego wiele. Punktów niewidocznych nie stawiam.
@Laoo: dzięki za rady, chyba najrozsądniej będzie tak zrobić.
Zaloguj się lub zarejestruj by napisać odpowiedź
atari.area forum » Programowanie - 8 bit » stawianie punktu w 3d
Wygenerowano w 0.030 sekund, wykonano 60 zapytań