2009-01-19:

SIN*COS

c++:easy:gfx
drillDzisiejszy post nie będzie już o cmd.exe i BATach. Zamiast tego dzisiaj będzie trochę rysowania w C++, a konkretniej rysować będziemy nie my, a funkcje sin oraz cos.

Jak zwykle historia zaczęła się 100 lat temu, kiedy to w którymś Bajtku pojawił się artykuł o uzyskiwaniu fajnych (precyzyjne pojęcie, nie ma co) rysunków na ekranie dzięki funkcjom sinus oraz cosinus. Obrazki były na prawdę bardzo fajne (rendering był "animowany", tzn było to tak wolne, że chwilę było trzeba czekać żeby trochę linii na ekranie się pojawiło ;>), i wyglądały bardzo naukowo ;D

Po stu latach postanowiłem wrócić do tematu (czytając moje posty można wywnioskować że mam grubo powyżej 100 lat, a informatyzacja zaczęła się przynajmniej w 19 wieku; w związku z czym proszę NIE powoływać się na mojego bloga podczas odpowiedzi z historii :D). I stworzyłem program który wywołuje sinus i cosinus w pętli (i to nawet dwa razy!), po czym stawia piksel w otrzymanym miejscu (oczywiście zieeelony pixel). Całość programu można streścić następującym pseudokodem:

for(i = 0; i < iter; i++)
 {
   rt += ratio;
   x += sin(rt*A) * cos(rt*C);
   y += sin(rt*E) * cos(rt*G);
   putpixel(x, y, HACKISH_GREEN);
 }


Okazuje się że dobierając zmieniając współczynniki A E C G można uzyskać baaardzo interesujące efekty - sześcian, logo batmana, etc - patrz galeria na dole posta.

Kod programu razem z binarką można ściągnąć poniżej. A teraz krótki kurs obsługi. Programem sterujemy za pomocą klawiatury. Pewne informacje wypisywane są na stdout. I po za tym nie ma żadnego interfejsu. Jeżeli chodzi o klawiaturę:

Q - zwiększenie współczynnika A o deltę
A - zmniejszenie współczynnika A o deltę
W - zwiększenie współczynnika C o deltę
S - zmniejszenie współczynnika C o deltę
E - zwiększenie współczynnika E o deltę
D - zmniejszenie współczynnika E o deltę
R - zwiększenie współczynnika G o deltę
F - zmniejszenie współczynnika G o deltę

3 - zwiększenie delty 10 razy
4 - zmniejszenie delty 10 razy

5 - zwiększenie prędkości zmiany kątów (ratio w pseudokodzie)
6 - zmniejszenie prędkości zmiany kątów (ratio w pseudokodzie)

0 - refresh
9 - tzw 'fit to window'

strzałki - przesunięcie obrazu
Z - zwiększenie powiększenia na osi X
X - zmniejszenie powiększenia na osi X
C - zwiększenie powiększenia na osi Y
V - zmniejszenie powiększenia na osi Y

B - zwiększenie liczby iteracji o 1kk
N - zmniejszenie liczby iteracji o 1kk

1 - zwiększenie intensywności kolorów
2 - zmniejszenie intensywności kolorów

M - screenshot do pliku RAW (RGB 1024x1024) + zapisanie w pliku "fajne.txt" informacji o współczynnikach/koordynatach

OK, chyba tyle. Dodam że program w postaci binarnej działa w rozdzielczości 1024x1024. Niestety, kod jest dostosowany do Windowsa, może potem wrzucę port na Linux-based OSy.

sincos.zip (22kb)

at_batman.pngat_chaossth.pngat_cube.png
at_cube2.pngat_drill.pngat_flower.png
at_multisin.pngat_rocket.pngat_sfinx.png
at_sth1.pngat_sth2.png

Comments:

2009-01-19 14:58:10 = mt3o
{
To ściema z tymi sześcianami, one mają zaokrąglone boki :P

Po sesji projekt obejrzę dokładniej, wygląda ciekawie.

Zastosowałeś jakąś optymalizację kodu?
}
2009-01-19 17:36:31 = ged_
{
Wiem, ze soft nie byl pisany z mysla o mega predkosciach, a ze jakos mi sie nie chce spac, wiec pogrzebalem za wzorami na sinusy:

sin(A+eps) = sinA * cos(eps) + cosA * sin(eps)

eps = ratio
sin(eps),cos(eps) = stale
sinA mamy z poprzedniej iteracji
a dla cosA trzeba napisac podobny wzor :)

Czyli zamiast wywolania sinusa, mamy 2 mnozenia i dodawanie, powinno troche kopnac :).

Rzeczywiscie fajne te obrazki :)
}
2009-01-19 17:39:53 = ged_
{
PS
Masz zjebany zegarek ;D
}
2009-01-19 21:18:34 = Gynvael Coldwind
{
@mt3o
Ba że ściema ;> Ale jaka ładna ;D
Jak zwykle optymalizacji brak. Szczerze to kod klepałem na kolanie w pociągu, i oprócz pobawienia się nim trochę, to dużo przy nim nie grzebałem ;>

@ged_
Nice work ;> Bardzo fajna metoda na optymalke, faktycznie kopa powinno dać ;>
A co do zegarka, to jest OK. Po prostu serv stoi w USA i wyświetla lokalną dla siebie godzinę ;p

}
2009-01-20 07:30:11 = mik01aj
{
Też chciałbym mieć czas na takie zabawy :)
btw - tu masz zabawkę opartą na podobnych wzorach: http://fyre.navi.cx/about.shtml
}
2009-01-20 08:34:15 = Gynvael Coldwind
{
@mik01aj
Thx za linka ;> Ktoś dał radę ;>
Myślałem kiedyś czy by nie zająć się trochę bardziej generowaniem obrazów proceduralnie (a szczególnie takich nadających się na tapetkę ;>)... Może i kiedyś się pobawie ;D
}
2009-01-21 11:01:25 = XANi
{
Hyhy, przypomniały mi się czasy gdy byłem młody (chyba miałem wtedy ~10lat) i wyklepałem w BASICu (nie znałem wtedy żadnego innego języka ;p ) programik odbijający piłkę w pudełku (potem w wielokącie.... potem były jakieś kółka ale że nie miałem zbytniego pojęcia jak zrobić by piłka odbijała się pod właściwym katem to na tym się skończyło ;] ).
No i były jeszcze oczywiście trainery... siedziało się z alt tabem i szukało grupki bajtów odpowiadającej za kasę.... niby niezbyt trudne ale dające dużo satysfakcji ;]. A jak raz hexeditorem podrasowałem sobie czarne smoczki to już wogóle byłem dumny z siebie ;]
}
2009-01-21 13:47:36 = Gynvael Coldwind
{
@XANi
Hehe czarne smoczki i hex edytor... to skąś znam ;D
}
2009-01-21 14:10:40 = zią
{
sinus cosinus dej pan trzy minus jak powiedział student na ustnym z matmy
}
2009-01-24 00:39:57 = Gynvael Coldwind
{
@zią
Prawie jak zaklęcie ;> Osobiście wolę metodę zoologiczną - na pandę ;>
"Paaanieee... pan da tróje" ;D
}
2009-01-24 08:10:53 = TBH
{
Port na *nixy chyba nie będzie potrzebny, na wine śmiga aż miło ;)

Generalnie fajny efekt, gratuluję.
}
2009-01-24 10:21:51 = Gynvael Coldwind
{
@TBH
Dobrze wiedzieć że na Wine śmiga ;>
Chociaż natywny port to natywny port ;>
}
2009-02-05 09:25:11 = rAum
{
Pierwsze słowo jakie mi wpadło do głowy to nic innego atraktor czyli wytwór chaosu :D
Kiedyś się tym zabawiałem :)

Proponuję zapoznać się z tym tematem, zwłaszcza porównać z atraktorem Peter De Jong :P

A zresztą, to pseudokod na De Jonga to:
for (duzo)
{
xn = sin(a * y) - cos(b * x),
yn = sin(c *x) - cos(d * y)
draw(xn,xn);
x = xn;
y = yn;
}

a nieskromnie zarzucę linkiem do mojej animacji (zmiana parametrow a,b,c,d w czasie): http://www.youtube.com/watch?v=xH2Q44JQHo0
}
2009-02-05 11:53:53 = Gynvael Coldwind
{
@rAum
Szczerze to przypomniałem sobie o temacie jak ktoś o właśnie atraktorach na GDPL napisał ;;>

Anyway, wzorek pewnie wrzucę w kod jak tylko będę miał chwile ;> Thx ;>

Animacja bardzo fajna ;> Aa to też rzucę linka:
http://vexillium.org/img/unav2.jpg
http://vexillium.org/img/unav1.jpg
http://vexillium.org/?art
To praca Unavoweda z wewnętrznego compo vexillium, 4KB binarka rysująca atraktor realtime, pod Linux-based OSy.

}
2009-02-05 23:55:01 = rAum
{
Na gdpl napisałem posta z kilkoma innymi wzorami, jak chcesz możesz sprawdzić:
http://forum.gamedev.pl/index.php/topic,6402.msg86977.html#msg86977

Ja też napisałem taką małą aplikację, zajmuje 1,48 KB (crinkler) normalnie 5,5 KB (VS).
http://r3v3x.uw-host.org/apps/atraktor.exe

W ogóle nie zoptymalizowane (CPU killer :P), moja wiedza z OpenGLa była niska, i chyba nie działa na Viście, ale pod Wine może dać się uruchomić :P

Za to muzyczka jest o tyle ciekawa że jest generowana poniekąd fraktalowo, proceduralnie :D Ale całkiem niezłe dźwięki wydaje :P
}
2009-02-06 13:02:20 = Gynvael Coldwind
{
@rAum
O dziwo działa nawet na Viście ;>
Muzyczka? Ehm, nie zauważyłem występowania muzyczki ;<
UPDATE: a nie, kłamie.. jest muzyczka ;>
Nie udostępnił byś czasem src ? ;>
}
2009-02-07 03:20:17 = rAum
{
A proszę bardzo:
http://r3v3x.uw-host.org/apps/atraktor-src.zip

W sumie to fragment większego, beznadziejnego programu więc trochę śmieci mogło zostać i ogólnie to dałoby się to 1000 razy lepiej napisać :)
}
2009-02-08 23:22:25 = Gynvael Coldwind
{
@rAum
Thx ;>
}

Add a comment:

Nick:
URL (optional):
Math captcha: 8 ∗ 4 + 1 =