Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 4 gru 2024, o 22:06


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 12 ] 
Autor Wiadomość
PostNapisane: 14 lis 2017, o 00:15 
Offline
Nowy

Dołączył(a): 28 sty 2015
Posty: 9
Pomógł: 0

Pierwszy post na forum, wypada się przywitać, a więc
Dobry wieczór :)

Kombinuje nad generowaniem losowej zawartości dla tablicy trójwymiarowej niech to będzie char tablica[8][8][8];
Chcę to wykorzystać do mojej led cube, tablica jest wizualizacją całej kostki, 1 oświeca diodę. Chcę żeby w każdej płaszczyźnie było dokładnie 8 elementów; w osi z (pionowo) będzie 8 płaszczyzn x na y. Trudno jest mi to nawet jakoś sensownie wytłumaczyć. Musi być dokładnie 64 elementów (jedynek) rozstrzelonych na całą objętość kostki, ale nie powtarzających się elementów, coś na wzór sudoku(mi to się z tym kojarzy). Miliony godzin, pętli i warunków i albo generuje śmieci, albo pętla losująca się zatrzymuje i program staje.
Piszę w C, dla AVR, dokłądniej atmega1284p. Proszę o podsunięcie idei. Czasem przy problemach z losowanie dodawałem do pętli flagę, warunek o przepełnieniu do while i potem jakiś debug, ale tu debug i przypisywanie elementów na sztywno to nie to co chcę osiągnąć.

Myślałem nad czymś takim, ale generuje 2 elementy i się wysypuje, avr staje.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 14 lis 2017, o 06:43 
Offline
Użytkownik

Dołączył(a): 29 paź 2017
Posty: 230
Pomógł: 26

Witaj.
Robisz teraz pętlę która losuje 64 razy współrzędne x,y,z.

A gdyby tak wewnątrz pętli zawrzeć warunek że
jeśli dioda o współrzędnych x,y,z została już wylosowana to zmniejszmy wartość licznika o 1
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Wtedy program tak długo będzie losował aż zapali 64 diody.
(wypełni Twoją tablicę 64 losowo wybranymi jedynkami)

P/S
Jechałem sobie do pracy i cały czas mnie ten Twój temat szturchał
Wziąłem kartkę i namalowałem sobie tablicę 4y * 4x
Zacząłem "zapalać" kolejne diody i zonk.

Obrazek
Po tych malunkach wyszło że aby zapamiętać wylosowane współrzędne 64 diod należało by wygenerować tablicę
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Wtedy wypełniając tę tablicę losowo wybranymi wartościami miałbyś współrzędne którymi mógłbyś "dokarmiać" diody
Może się mylę



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 14 lis 2017, o 10:16 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 mar 2014
Posty: 1475
Pomógł: 167

Problemem Twoim jest, że losujesz cały czas z całej tablicy. Więc jak masz więcej zaświeconych diod, to zanim trafisz na nie zaświeconą to trwa to coraz dłużej. A przy ostatnich możesz bardzo długo czekać aż na nie trafisz.
Rozwiązaniem w PC byłoby zrobienie listy na początek ze wszystkimi elementami i po wylosowaniu usuwanie wylosowanego z niej. Czyli zmniejszanie długości listy o 1 i kolejne losowanie już ze zmniejszonej liczby elementów.
W AVR masz niestety mniej pamięci i coś takiego jest trudno zrobić, ale najlepiej byłoby tak pokombinować.

--
Pozdrawiam,
Robert

------------------------ [ Dodano po: 2 minutach ]

Prosty rozwiązaniem jest zrobić tak, że jak wylosujesz już zapalony element to zapalasz następny "wolny" (nie zapalony), tak jakby to tamten był wylosowany. Przez co masz zawsze trafienie :).

------------------------ [ Dodano po: 12 minutach ]

A innym rozwiązaniem jest, gdy każda dioda to u Ciebie jeden bajt (choć to bardzo rozrzutne ;)), to zrobienie tak:
Na początku dla każdej diody losujesz wartość losową i zapisujesz w jej komórce. Czyli każda dioda ma jakąś nieunikalną (ale nam to nie przeszkadza) wartość ale różniącą od większości innych wartość. Robisz to przed przystąpieniem do zapalania.
Potem przelatujesz tablicę i zapalasz kolejno diody mające wartości w tablicy od najmniejszej do największej - znajdujesz najmniejszą wartość i zapalasz jej diodę. Potem szukasz czy nie ma innej takiej samej i jak jest to ją zapalasz w kolejnym kroku. Jak już nie ma to zwiększasz i szukasz o 1 większej. I tak do zapalanie wszystkich.
Aby nie zapalać diod o tej samej wartości zawsze od dołu do góry (lekko możesz zaburzyć losowość), to możesz przy każdej przeszukiwanej wartości zmieniać kierunki przeszukiwania tablicy.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 14 lis 2017, o 10:53 
Offline
Nowy

Dołączył(a): 28 sty 2015
Posty: 9
Pomógł: 0

Zrobiłem wczoraj jeszcze próbę z losowaniem jednej zmiennej;
for z 0-7, for y 0-7
x=losuj(0, zakres)

(losuje 8 razy w do while i zmniejszam zakres)

gdzie zrobiłem tablice dla iksów, o wartościach 0 do 7, wybrany x jest zastępowany ostatnim, tak żeby wykorzystać wszystkie 8 współrzędnych, sprawdzanie we wszystkich płaszczyznach i mały debug.
Rozwinę jeszcze założenia. Funkcja na początku losuje oś wzdłuż której będzie rysowana animacja, losuje kierunek. Pierwsza ściana się wypełnia, przesuwa się o 1, usuwa 8 pikseli które zostały na pierwszej ścianie i reszta przesuwa się wzdłuż osi animacji, tak 8 razy aż na ostatnią ścianę dociera 8 pikseli. Tu następuje druga, powrotna cześć funkcji, znowu losowa oś i kierunek (w przód lub w tył) i następuje zbieranie ścian aż do ostatniej na której powinny znaleźć się wszystkie 64 elementy. Niestety nie we wszystkich osiach to działa, jeśli działa w osi x i y, to w osi z już będzie brakowało kilku pikseli ponieważ współrzędne się dubluja a innych nie ma wcale.

Cała moja kostka opiera się o tablicę cube|8][8][8] dla Z Y i X, jeśli będzie to cube[5][1][0]=1, to zapali się dioda dokładnie o tych współrzędnych. Gdyby zrobić listę dostępnych współrzędnych, każdy piksel wylosowany musiałby od razu blokować 7 innych, a ja już kompletnie nie wiem jak to ugryźć.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 14 lis 2017, o 11:07 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 mar 2014
Posty: 1475
Pomógł: 167

Kentsel napisał(a):
Tu następuje druga, powrotna cześć funkcji, znowu losowa oś i kierunek (w przód lub w tył)

Napisz dokładniej co tutaj robisz, bo przynajmniej ja, nie rozumiem z tak lakonicznego opisu :(.

--
Pozdrawiam,
Robert



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 14 lis 2017, o 11:42 
Offline
Nowy

Dołączył(a): 28 sty 2015
Posty: 9
Pomógł: 0

Kostka ma 3 osi, pionowo z, w poziomie x i y. Animacja dla osi z, odbywa się w pionie, góra ma wartość 0, dół 7, animacja w przód dla osi z znaczy od 0 do 7 a więc z góry na dół, w tył od 7 do 0 czyli w górę.

3 etapy działania:
1 generowanie losowej kostki, 64 piksele
2 wypisanie na pierwszej ścianie animacji wszystkich 64p, ściana przesuwa się o 1, zostaje 8p na ścianie 1 wg wcześniej wylosowanych, te 8p jest odejmowane od tamtych 64, więc zostaje 56 na ścianie 2. Przesunięcie o 1, pozostawienie 8p, 48 jedzie dalej. Aż do 8 ściany gdzie pozostaje 8p, założenia projektu, na każdej ścianie 8p o indywidualnych współrzędnych.
3 animacja odwrotna, od dowolnej brzegowej ściany, 8p, przesuwa się na kolejną ścianę i dodaje, w efekcie ściana 1 ma 0p ściana 2 16p, itd aż do ostatniej ściany na którą zbiera wszystkie 64p.
Ja to widzę, wydaje mi się to łatwe, a zarazem trudne do wytłumaczenia. Może mam w telefonie nagraną animacje.

Wysłane z mojego E5603 przy użyciu Tapatalka

------------------------ [ Dodano po: 25 minutach ]

https://drive.google.com/file/d/1CI4UmDDcXPCizUcMaII3lDkHTEVxSgIl/view?usp=drivesdk (180 MB)
Stare nagranie ale pokazuje zasadę działania.

------------------------ [ Dodano po: 29 minutach ]

Opisana animacja zaczyna się od 1:32



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 14 lis 2017, o 17:16 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 11 mar 2014
Posty: 1475
Pomógł: 167

Kentsel napisał(a):
1 generowanie losowej kostki, 64 piksele
Co znaczy dowolnej kostki? Czy to są dowolne 64 pixele ze wszystkich 512? Jak one wpływają na kolejne punkty?
Czy te znikające pixele w drugim punkcie to te wylosowane w pierwszym kroku? Jak tak to w pierwszym nie mogą być dowolnie losowe pixele , tylko po 8 na każdą warstwę, w dodatku unikalne.

--
Pozdrawiam,
Robert



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 14 lis 2017, o 17:28 
Offline
Nowy

Dołączył(a): 28 sty 2015
Posty: 9
Pomógł: 0

Losuje całą kostkę, 64/512. Unikalne? Owszem właśnie po to ten temat :D losuje od razu 64 punkty w zmiennej pomocniczej. Problem w tym, że nie wiem jak wygenerować idealnie unikalne piksele.

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

to generuje kostkę, 64 piksele, ale zawsze znajdzie się kilka błędów, zawsze wzdłóż jednej z osi powtarzają się wpółrzędne. Np pierwszy etap animacji czyli wypisanie, było w osi X, to 2 etap czyli zebranie pikseli z powrotem na jedną ścianę, to uda się w osi X i Y, ale w Z już nie.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 14 lis 2017, o 20:51 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

Nie jestem pewny, czy o to Ci chodzi, ale poniższy sposób spowoduje wygenerowanie tablicy, w której w dowolnym rzędzie w dowolnej osi będzie zapalona jedna i tylko jedna dioda. Nie chce mi się za bardzo opisywać szczegółowo kodu, więc mam nadzieję, że zrozumiesz ideę. To tylko wygenerowanie tablicy, animację musisz sobie wykombinować sam, ale to już chyba mniejszy problem.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


_________________
AVR-GCC - dane w pamięci FLASH



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 14 lis 2017, o 23:07 
Offline
Nowy

Dołączył(a): 28 sty 2015
Posty: 9
Pomógł: 0

Niewiele rozumiem, więc pewnie działa. Tylko nie wiem jak z tego wyjść na tablice cube[8][8][8]. Nie zależy mi na oszczędności pamięci ;) Wygląda mi to na fragment kodu z innej led cube. Kiedyś prrzeglądałem "gotowce", ale nie korzystałem, bo raz że zmieniłem schemat troszkę, włożyłem inne kości do multipleksowania, a dwa że piszę kod od podstaw sam i trudno będzie mi wkomponować coś czego nie rozumiem :/



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 lis 2017, o 11:15 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

Kentsel napisał(a):
Wygląda mi to na fragment kodu z innej led cube.

Nie, to nie jest fragment gotowego kodu, to moja propozycja napisana według Twojego opisu.

Kentsel napisał(a):
Nie zależy mi na oszczędności pamięci...
Kiedyś przeglądałem "gotowce", ale nie korzystałem, bo raz że zmieniłem schemat troszkę, włożyłem inne kości do multipleksowania

To nie tylko kwestia oszczędności pamięci. Większość operacji na tablicy 512 elementowej będzie trwała zdecydowanie dłużej.
Moja propozycja to tablica 8x8. Wymiary tablicy to osie x i y. Każdy bajt w tablicy reprezentuje 8 diod w osi z. Oczywiście nazewnictwo osi to kwestia umowna, można zmienić kolejność wedle uznania.
Nie wiem jak to multipleksujesz, myślę jednak, że organizacja tablicy nie ma na to większego wpływu. Podejrzewam nawet, że moja propozycja działałaby szybciej, ponieważ łatwiej odczytać 64 bajty (gotowe całe rzędy diod w jednym bajcie) niż odczytywać 512 bajtów i z każdego wydobywać 1 bit. Sama kalkulacja adresu tablicy trójwymiarowej będzie trwała dłużej, a trzeba to przemnożyć przez ilość odczytywanych bajtów.

Kentsel napisał(a):
Musi być dokładnie 64 elementów (jedynek) rozstrzelonych na całą objętość kostki, ale nie powtarzających się elementów, coś na wzór sudoku(mi to się z tym kojarzy). Miliony godzin, pętli i warunków i albo generuje śmieci, albo pętla losująca się zatrzymuje i program staje...

Gdyby zrobić listę dostępnych współrzędnych, każdy piksel wylosowany musiałby od razu blokować 7 innych, a ja już kompletnie nie wiem jak to ugryźć...

Czasem przy problemach z losowanie dodawałem do pętli flagę, warunek o przepełnieniu do while i potem jakiś debug, ale tu debug i przypisywanie elementów na sztywno to nie to co chcę osiągnąć....


Właśnie problem w tym, że w taki sposób - jak sam zauważyłeś - trudno będzie Ci osiągnąć cel.

Próbowałem podsunąć następujące rozwiązanie - nieco odmienne podejście. Wyobraźmy sobie ścianę kostki x-y jako 64 elementy (8x8). Każdy element zawiera liczbę, która jest numerem (identyfikatorem) diody która się świeci w osi z.
Jeśli teraz utworzymy takie Twoje sudoku:
Kod:
             x

      0 1 2 3 4 5 6 7
      1 2 3 4 5 6 7 0
      2 3 4 5 6 7 0 1
 y    3 4 5 6 7 0 1 2
      4 5 6 7 0 1 2 3
      5 6 7 0 1 2 3 4
      6 7 0 1 2 3 4 5
      7 0 1 2 3 4 5 6

to mamy pewność, że patrząc na dowolną płaszczyznę będziemy widzieć 64 diody pokrywające całą płaszczyznę, po jednej pod każdą współrzędną danej płaszczyzny.

Ten wzór jest jednak regularny, a nie o to chodzi. Przyjmijmy jednak to za pozycję wyjściową. Jeśli teraz spróbujemy zrobić tak:
Kod:
    zamieniamy 2 losowe wiersze
         pomiędzy sobą

             x

      0 1 2 3 4 5 6 7
      5 6 7 0 1 2 3 4
      2 3 4 5 6 7 0 1
 y    3 4 5 6 7 0 1 2
      4 5 6 7 0 1 2 3
      1 2 3 4 5 6 7 0
      6 7 0 1 2 3 4 5
      7 0 1 2 3 4 5 6


    a później 2 losowe kolumny

                x

      0 6 2 3 4 5 1 7
      5 3 7 0 1 2 6 4
      2 0 4 5 6 7 3 1
 y    3 1 5 6 7 0 4 2
      4 2 6 7 0 1 5 3
      1 7 3 4 5 6 2 0
      6 4 0 1 2 3 7 5
      7 5 1 2 3 4 0 6


to już to wygląda trochę lepiej, a nadal zachowujemy odpowiednie relacje we wszystkich wierszach i kolumnach. Jeśli powtórzymy tę operację kilkadziesiąt razy stosując losowe numery wierszy i kolumn, uzyskamy przypadkową i niepowtarzalną kombinację cały czas zachowując założone reguły (jedna dioda w każdym rzędzie).

Warunkiem jest oczywiście uzyskanie naprawdę losowych liczb, bo w AVR to nie jest proste.

To co opisałem powyżej zrealizowałem w przedstawionym wcześniej kodzie na tablicy mojej konstrukcji. Na pewno da się to też zrealizować na Twojej tablicy, jednak będzie to trwało zdecydowanie dłużej. U mnie wygenerowanie tablicy przy 53 iteracjach pętli (być może wystarczy mniej, trzeba byłoby przetestować) trwało niecałe 12ms dla zegara 16MHz.

Mam nadzieję, że było zrozumiale i że koncepcja się przyda.

_________________
AVR-GCC - dane w pamięci FLASH


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 lis 2017, o 19:28 
Offline
Nowy

Dołączył(a): 28 sty 2015
Posty: 9
Pomógł: 0

No teraz trochę zrozumiałem. Nie jestem programistą, kostka to moje hobby, przy okazji się uczę. Procedura przerwania napisana prze ze mnie wyświetla na bieżąco stan tablicy cube[8][8][8], na chwilę obecną mam 12 różnych animacji i wszystkie bazują na trójwymiarowej tablicy, chcę przy tym pozostać. Łącząc mój kod i Twój pomysł musiałbym mieć wygenerowane 8 tablic, i zamieniać tylko wiersze/kolumny żeby uzyskać wrażenie, że jest wypełniona inaczej. Wciąż nie wiem jak do tego wrzucić trzeci wymiar. Jestem świadom że mój kod nie jest optymalny, wystarczy mi że działa sprawnie, 20MHz, przerwania z Timera2, UART1 połączony z bluetooth i aplikacja służąca jako pilot zdalnego sterowania.


I nagle mnie oświeciło.
Czy po prostu w tym z=tablica[x][y] ?
właściwie to tak

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Zmieniłem zdanie, jesteś wielki, dziękuję bardzo :)


edit:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

n razy (1-5) zamieniam 2 losowe wiersze i 2 losowe kolumny, efekt jest zadowalający, trudno powiedzieć czy kombinacje się powtarzają, ale zawsze są unikalne punkty :)

Dziękuję raz jeszcze, temat się wyczerpał.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 12 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Google [Bot] i 1 gość


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO