Oryginalna strona colobot.cba.pl umarła, gdy cba.pl przestało oferować darmowy hosting. To jest statyczny mirror, pobrany w 2018. ~krzys_h
 Polski Portal COLOBOTa - COLOBOT Polish Portal
Forum - Polski Portal COLOBOTa
Strona głównaStrona główna UżytkownicyUżytkownicy GrupyGrupy StatystykiStatystyki


Poprzedni temat «» Następny temat
jak zrobić goto
Autor Wiadomość
adiblol 
Administrator forum
FLOSS FTW!


Twoja ulubiona misja: porównywanie formatów audio
Pomógł: 18 razy
Dołączył: 21 Kwi 2008
Posty: 1313
Skąd: pokój odsłuchowy
Wysłany: 26-12-2009, 14:09   

Berserker napisał/a:
bez podjezdzania robotem w dane miejsce, sprawdzania kierunku i wracania

Nie wiedziałem.

Ale można tak (UWAGA teoria rodem z postów pipoka!):


(źródło: patrz URL obrazka)


(źródło: Wikipedia, "Funkcje trygonometryczne")


(źródło: własne :) )

A - działo, "dany punkt"
B - siedziba Microsoftu (cel)
C - nieistotne

alfa - trza obliczyć
beta - orientacja działa
gamma - potrzebny obrót

Musimy obliczyć alfę:
z tabelki bierzemy a/b albo b/a, ja wybrałem a/b czyli tan alfa (w programowaniu jest tan, w matematyce tg).
Kod:

tan(alfa) = c/b
alfa = ?

i wychodzi nam
Kod:
alfa = atan(a/b);

dzięki arcusom (newbies odsyłam na Wikipedię)

Dalej już prosto :)
Aby obliczyć obrót (gammę) trzeba od orientacji (bety) odjąć alfę.

Cały algorytm:
(kod jest trochę bardziej skomplikowany bo trzeba liczyć a i b)
Kod:

object ms = radar(Microsoft);
point siedziba_microsoftu = ms.position;
object shooter = radar(WingedShooter);
point dzialo = shooter.position;

float beta = shooter.orientation;
float a = siedziba_microsoftu.y - dzialo.y;
float b = siedziba_microsoftu.x - dzialo.x;
float alfa = atan(a/b);
float gamma = beta - alfa;



UWAGA mogłem się pomylić ze znakiem funkcji turn() bo dawno nie grałem, jak coś źle działa to zamiast gamma=beta-alfa dajcie gamma=alfa-beta, będzie to odpowiadało zmianie znaku ;)

NIE TESTOWANE (nie mam Colobota)
_________________
1Tbps Project && Telecomix Network

 
 
     
Berserker 
Dark Ness


Twoja ulubiona misja: Ofrenia
Pomógł: 16 razy
Wiek: 24
Dołączył: 24 Mar 2009
Posty: 496
Skąd: Bigos
Wysłany: 26-12-2009, 20:36   

@up
Dziala z pewnymi poprawkami.

@topic
Narazie usiluje napisac tak funkcje Goto(), zeby mogla przejsc cwiczenia "Stacje przekaznikowe" 1 i 2. Aktualnie robot pakuje sie centralnie w mine i probuje sprawic, by ja omijal. Jak ktos chce sie pobawic:
Kod:
int object::Goto(point pos)
{
    ipf(1000);
    point center, dest[]; //punkty sciezki
    point F, R, L, adest; //punkty docelowe
    int list[], i;
    float len; //odleglosc do nastepnego punktu
    float lenstart;
    float dir;
    float orient;
    center = position;
    lenstart = 0.5; //odleglosc domyslna miedzy kolejnymi punktami
    do
    {
        len = lenstart;
        orient = getOrient(center, pos); //kierunek pozycji docelowej
        F = getPos(center, orient, len); //oblicz pozycje w kierunku pozycji docelowej
        if(OK(center, F) == true) //sprawdz, czy osiagniecie jej jest mozliwe
        {
            adest = F;
        }
        else
        {
            i = 0;
            do
            {
                i++;
                L = getPos(center, orient+i*5, len); //oblicz pozycje skierowana o 5dgr na lewo
                R = getPos(center, orient-i*5, len); //oblicz pozycje skierowana o 5dgr na prawo
                if(i >= 180/5) // jesli program zatoczy kolo
                {
                    i = 0; //ustal mnoznik stopni na 0
                    len += 0.5; //zwieksz odleglosc do kolejnego punktu o 0.5m
                }
            }
            while(OK(center, L) != true and OK(center, R) != true);
            if(topo(L) < topo(R)) adest = L;
            else adest = R;
           
        }
        center = adest;
        dest[sizeof(dest)] = adest; //dodaj nowy punkt do sciezki
        if(sizeof(dest) > 9999) //jesli ilosc punktow w sciezce jest za duza
        {
            return 1; //przerwij
        }
       
    }
    while(distance2d(center, pos) > 2);
    dest[sizeof(dest)] = pos; //dodaj punkt o wspolrzednych punktu docelowego
    i = 0;
    while(distance2d(pos, position) > 1 and i < sizeof(dest))
    {
        adest = dest[i++]; //uzyskaj kolejny punkt sciezki
        while(distance2d(position, adest) > 0.2) //i dojedz do niego
        {
            dir = direction(adest);
            len = distance(position, pos);
            len = len/5;
            if(len > 1) len = 1;
            //motor(1-dir/90, 1+dir/90);
            turn(dir);
            motor(len, len);
        }
    }
    motor(0, 0);
    return 0;
}
bool object::OK(point center, point dest) //sprawdzanie czy punkt jest osiagalny
{
    int list[];
    float radius[];
    object p;
    list[Mine] = Mine;
    radius[Mine] = 2.5;
    p = search(Mine, dest);
    if(p != null)
    {
        if(distance(p.position, dest) < radius[p.category]) return false;
    }
    return true;
}
point getPos(point center, float orient, float lenght) //otrzymaj punkt w danym kierunku
{
    point dest;
    dest.x = center.x+cos(orient)*lenght;
    dest.y = center.y+sin(orient)*lenght;
    dest.z = topo(dest);
    return dest;
}
float getOrient(point center, point dest) //uzyskaj kierunek
{
    float x, y;
    float angle;
    y = dest.y-center.y;
    x = dest.x-center.x;
    if(x == 0)
    {
        if(y > 0)
        {
            angle = 90;
        }
        else
        {
            angle = 270;
        }
    }
    else
    {
        angle = atan(y/x);
        if(x < 0)
        {
            angle += 180;
        }
    }
    return angle;
}
Ostatnio zmieniony przez Berserker 27-12-2009, 21:42, w całości zmieniany 1 raz  
 
 
     
sajmon313 
Jedi Master


Wiek: 28
Dołączył: 16 Gru 2009
Posty: 42
Skąd: /dev/uarndom
Wysłany: 27-12-2009, 21:09   

@up
Może dopisz komentarze w kodzie, coby był bardziej czytelny?
Chociaz ogólnikowo, do czego funkcja, do czego zmienna (przy jej deklaracji), itp.
_________________
Validator CBot - Prace Trwają
Ostatnia Aktualizacja: 02.01.10
 
 
     
Berserker 
Dark Ness


Twoja ulubiona misja: Ofrenia
Pomógł: 16 razy
Wiek: 24
Dołączył: 24 Mar 2009
Posty: 496
Skąd: Bigos
Wysłany: 27-12-2009, 21:45   

@up
Edytowalem poprzedni post, dodalem tez troche zmian, teraz robot zgrabnie omija miny i ladnie laduje w docelowym punkcie :)
_________________
 
 
     
sajmon313 
Jedi Master


Wiek: 28
Dołączył: 16 Gru 2009
Posty: 42
Skąd: /dev/uarndom
Wysłany: 28-12-2009, 10:35   

teraz dobrze.

Ale w funkcji OK, dlaczego sprawdzasz tylko miny? A jeżeli będzie tam stała fabryka robotów? Albo królowa obcych?

Tylko dla miny znamy radius, dla innych obiektów trzeba będzie wyznaczyć eksperymentalnie.

i w ostatniej linii tej funkcji ja bym (tak dla pewności) dał:
Kod:
else return true;
_________________
Validator CBot - Prace Trwają
Ostatnia Aktualizacja: 02.01.10
 
 
     
Berserker 
Dark Ness


Twoja ulubiona misja: Ofrenia
Pomógł: 16 razy
Wiek: 24
Dołączył: 24 Mar 2009
Posty: 496
Skąd: Bigos
Wysłany: 28-12-2009, 13:04   

Cytat:
Ale w funkcji OK, dlaczego sprawdzasz tylko miny? A jeżeli będzie tam stała fabryka robotów? Albo królowa obcych?

Efekt tego, ze instrukcja search() nie wykrywa kategorii umieszczonych w tablicy jak radar(), trzeba napisac osobna funkcje.

Cytat:
Tylko dla miny znamy radius, dla innych obiektów trzeba będzie wyznaczyć eksperymentalnie.

Dla budynkow mozna wykorzystac powierzchnie potrzebna do budowy.
Cytat:
i w ostatniej linii tej funkcji ja bym (tak dla pewności) dał: Kod:
else return true;

Ja nie dam, na to samo wychodzi a pozniej bedzie jeszcze mnostwo warunkow.
_________________
 
 
     
adiblol 
Administrator forum
FLOSS FTW!


Twoja ulubiona misja: porównywanie formatów audio
Pomógł: 18 razy
Dołączył: 21 Kwi 2008
Posty: 1313
Skąd: pokój odsłuchowy
Wysłany: 29-12-2009, 17:07   

Nie trzeba sprawdzić eksperymentalnie, jest taki fajny plik na stronie Epsiteca... http://www.epsitec.ch/colobot/program/prog058.txt
_________________
1Tbps Project && Telecomix Network

 
 
     
gg
Gość


Wysłany: 25-02-2010, 21:59   a

a moze po kazdym "cyklu" znajdowania takiego punktu zrobic :

turn(direction(//nasz ce//.position));

a czy ktos wie jak napisac i odczytac wielolinijkowy plik by np. robic listy a'la tablice ?
 
     
Wyświetl posty z ostatnich:   

Wersja do druku

Skocz do:  

Powered by phpBB modified by Przemo © 2003 phpBB Group
Polski Portal COLOBOTa © 2008 - 2012