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ć.
Tydzień na oddanie głosu w FUJICUP! Głosowanie potrwa tylko do 22 lutego 2025...
TURGEN 9.3.1 Najnowsza wersja oprogramowania TURGEN wprowadza kilka istotnych ulepszeń.
FujiCup 2024 - głosowanie Wystartowało głosowanie w tegorocznej edycji konkursu FujiCup.
IX. Basque Tournament of Atari 2600 31 stycznia Euskal Retro Association zorganizowało IX. Baskijski Turniej Atari 2600.
Rogul 1.0f Poprawki i nowe funkcje
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.027 sekund, wykonano 69 zapytań