potrzebuje wyznaczyć kierunek z punktów osi XY. pobieram punkty i obliczamy odległość między punktami w pionie i poziomie potem znając dx i dy obliczyć kąt zawarty między odcinkiem a osią OX. Jest także wprowadzona tolerancja konta. każdy wyliczony kierunek oznaczamy liczbą od 1 do 8. jaki jest wzór na obliczenie kąta?
atan2(dy,dx)
mam punkty(x;y) A(51;52) B(101;102) D(150;50) tworzą one literę V
załużmy że kierunek prawo-dół to 1 a prawo-góra to 2.
- obliczyć odległość między punktami w pionie i poziomie
dx=101-51=50 dy=102-52=50
dx=150-101=49 dy=50-102=-52
2.obliczamy kąt między odcinkiem a osią OX
zgodnie z podanej wcześniej funkcji atan2(dy,dx)
0,785398
0,815092
co to są za kąty?
W radianach, spales na matematyce w gimnazjum?
dlaczego wychodzi mi minusowy kąt? w szkole miałem to bardzo dawno temu i nie pamięta wszystkiego. dzięki za pomoc
A(204;83) B(38;72)
dx=38-204=-166
dy=72-83=-11
atan2(-11,-166) ≈ -3,075
zamiana na stopnie
x [°] ≈ x [rad] ∙ 57,29577951308= -3,075 ∙ 57,29577951308 = -176,208834312628
co mam zrobić z minusowym kątem? jak mam to interpretować w związku z kierunkiem?
Ujemny kąt to nic złego przecież.
ale jak to mam znaleźć kierunek z tego kąta?
Używając funkcji trygonometrycznych sinus i cosinus lub zapisując deltax i deltay jako wektor i znormalizować go, aby otrzymać wektor jednostkowy (kierunkowy?). Wtedy nie musisz korzystać z żadnych kątów.
możesz dać jakiś przykład? obliczyć np z tych punktów co są podane?
Dobra.
Teraz przeczytałem temat dokładniej, przepraszam, że wcześniej tego nie zrobiłem.
Tak czy inaczej sprawa jest dosyć prosta.
Skorzystam do tego z wartości kąta jaką wyliczyłeś z atan2, bo tak będzie najprościej.
kierunek = (kąt+180)/8%8+1;
po (kat+180)/8 otrzymujemy wartość od 0 do 8 włącznie (8 dla kąta 360), aby tą 8 zamienić na 0 wykonujemy modulo, a potem przesuwamy wartości o 1 aby mieć je w przedziale 1..8
To który gdzie wskazuje nie potrafię Ci teraz powiedzieć, musisz samemu sprawdzić.
czyli wystarczy że podstawie kąt pod ten wzór (kąt+180)/8%8+1
"kąt" w działaniu ma być w radianach czy to jest kąt=atan2(dy,dx) ?
(atan2(dy,dx)+180)/8%8+1
aaaaaaaaa głupi jestem... Nie myślę już
(kastWStopniach+180)/45%8+1
Przepraszam za to zamotanie.
45, bo co 45 stopni zmienia się kierunek, prawda?
to przykładowo jak wcześniej liczyłem wyło mi -176 stopni
napisałem szybko program i mi wylicza 1.
(-176+180)/45%8+1= 1
część równania %8+1 mam liczyć tylko jeśli wychodzi z działania (kastWStopniach+180) 360stopni?
mi wyszło 5...
(kod w C):
double x = -166, y = -11;
double caly_obrot = M_PI * 2;
double jaka_czesc = atan2(y, x) / caly_obrot;
double stopnie = jaka_czesc * 360;
int kierunek = (jaka_czesc >= 0? jaka_czesc : jaka_czesc + 1) * 8 + 1;
kat w radianach: -3.075424
kat w stopniach: -176.208834
kierunek: 5
i wydaje mi się, że to jest prawidłowa odpowiedź (nawet patrząc na te liczby -166, -11 i próbując je sobie wyobrazić na osi), i że we wzorze Sopelka niepotrzebnie jest dodawana liczba 180 do kąta, albo czegoś nie rozumiem (co też jest możliwe).
Dobra przespałem się i mam nadzieję teraz nie dam totalnej plamy myślowej ;].
Żeby nie było niejasności.
Wtedy liczymy tak.
kąt = jakiś tam kąt w stopniach.
if(kąt<0) kąt += 360 //przekształcamy kąt na dodatni tak, aby była ciągłość (przeciwnie do wskazówek zegara od 0 do 360 stopni). poprawione
kąt += 22.5 //ustawiamy tak, aby kąt zerowy tak na prawdę był kątem -22.5. Ułatwi to obliczenia.
//trochę krzywo linie wyszły, ale te czerwone są takie same jak na pierwszym obrazku tylko obrócone.
kierunek = kąt/45+1 //bo co 45 stopni zmienia się kierunek począwszy od kąta 22.5 stopnia. możemy otrzymać wartości 1..9
if(kierunek == 9) kierunek = 1 //zmieniamy kierunek na 1 kiedy jest równy 9
tak to ma wyglądać?
z = Math.Atan2(y2 - y1, x2 - x1);
z = z * 57.29577951308; //przekształcanie z radianów na stopnie
if (z < 0) //warunek jeśli kąt jest ujemny
{
z = z + 360;
}
z = z / 45+1; //kierunek od 1-9
Zamiast z = z + 360 daj
if(z < 0) z += 360
ifa jakoś pominąłem
a dlaczego jest w działaniu z=z/45+1 te +1 na końcu?
trochę inaczej wychodzi to na wykresie
www.fotosik.pl/pokaz_obrazek/4c0ca877cc3b4f23.html
Dzwine.
funkcja atan2 powinna zwracać kąty w takim układzie jak zaznaczyłem, a wygląda tak, jakby zwracała na odwrót (ujemne na górze).
Albo liczysz delte w drugą stronę.
U mnie w C++ działa poprawnie.
http://screenshooter.net/2148672/lxfrptv
tu mam mam program który naskrobałem na szybko
http://przeklej.org/file/cSdLFs/WindowsFormsApplication1.exe
double x1, x2, y1, y2, z;
x1 = Convert.ToDouble(textBox3.Text);
x2 = Convert.ToDouble(textBox4.Text);
y1 = Convert.ToDouble(textBox6.Text);
y2 = Convert.ToDouble(textBox5.Text);
z = Math.Atan2(y2 - y1, x2 - x1);
textBox1.Text = z.ToString();
z = z * 57.29577951308;
textBox2.Text = z.ToString();
if (z < 0) z += 360;
z = z / 45+1;
textBox7.Text = z.ToString();
zapomniałeś jeszcze o zamienieniu 9 na 1 na końcu
Możliwe, że błąd jest tutaj. Jako, że wyniki są odwrócone względem osi y.
y1 = Convert.ToDouble(textBox6.Text); //chodzi mi o to, że możesz sczytywać na odwrót.
y2 = Convert.ToDouble(textBox5.Text);
Czy z*=180/M_PI;
zamiast z = z * 57.29577951308;
jest zbyt mainstremowe?
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main()
{
for(unsigned i=0;i<360;i+=1)
{
double dx=10*cos(i*(M_PI/180)),dy=10*sin(i*(M_PI/180));
cout
<<setw(3)<<i<<fixed
<<setprecision(2)<<setw(7)<<dx
<<setprecision(2)<<setw(7)<<dy
<<setw(2)<<((int)((4/M_PI*atan2(-dy,-dx)+4.5))%8+1)
<<endl
;
}
return 0;
}
nie wiem dlaczego ale robiąc warunki do kierunków cały czas pokazuje mi kierunek nr. 1 chce zrobić aby numery kierunków się nie powtarzały tzn. żeby nie było np pięć 1 obok siebie tylko jedna.
if (z < 1.49 | z > 8.49) kierunek = 1;
if (z > 1.49 & z < 2.49) kierunek = 2;
if (z > 2.49 & z < 3.49) kierunek = 3;
if (z > 3.49 & z < 4.49) kierunek = 4;
if (z > 4.49 & z < 5.49) kierunek = 5;
if (z > 5.49 & z < 6.49) kierunek = 6;
if (z > 6.49 & z < 7.49) kierunek = 7;
if (z > 7.49 & z < 8.49) kierunek = 8;
if (Convert.ToInt32(kierunekstr[kierunekstr.Length - 1]) != kierunek) //w tym warunku jest coś źle bo cały czas dodaje mi liczby chociaż porównuje mi ostatnią liczbę i tą którą chce zapisać
kierunekstr += kierunek.ToString();
proszę o pomoc
||
i &&
- Generalnie cale te ify sa bez sensu, uzyj czegos typu:
dict<pair<float, float>, int>
. Gdzie pair, bedzie twoja wlasna klasa majaca 2 floaty + metode sprawdzajaca czy miesci sie podany argument w zasiegu i zejdziesz do 2 linijek kodu uzytkowego.
ok. a co z tym warunkiem który ma zapisywać do zmiennej kierunekstr tylko pojedyncze liczby? myślę kombinuję i nic nie umiem z tym zrobić
- Czemu to trzymasz jako napisy?
- Czym jest
kierunekstr
? - Prawdopodobnie dziala tak jak napisales :]
nie wiem dlaczego ale robiąc warunki do kierunków cały czas pokazuje mi kierunek nr. 1 chce zrobić aby numery kierunków się nie powtarzały tzn. żeby nie było np pięć 1 obok siebie tylko jedna.
Ale to 'z' nie jest kątem w stopniach a nie w radianach? Jeśli tak to faktycznie prawie wszystko podpada pod 1
Generalnie cale te ify sa bez sensu, uzyj czegos typu: dict<pair<float, float>, int>. Gdzie pair, bedzie twoja wlasna klasa majaca 2 floaty + metode sprawdzajaca czy miesci sie podany argument w zasiegu i zejdziesz do 2 linijek kodu uzytkowego.
Ale to też bez sensu, przecież wystarczy coś w rodzaju (zakładając stopnie, i że na wejściu z jest z przedziału <0; 360) )
int kierunek = (int)((z + 22.5) / 45.0) % 8;