Oryginalna strona colobot.cba.pl umarła, gdy cba.pl przestało oferować darmowy hosting. To jest statyczny mirror, pobrany w 2018. ~krzys_h
|
Forum - Polski Portal COLOBOTa |
|
|
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
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ł:
|
_________________ 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
|
|
|
|
|
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 ? |
|
|
|
|
|
|
| |
|
|
|
|
Polski Portal COLOBOTa © 2008 - 2012 |
|
|