Problem z odejmowaniem w funkcji obliczającej kąt

0

Napisałem taki program:

 program Project3;

{$APPTYPE CONSOLE}

uses
  SysUtils;

  Type wektor=Array[1..10] of Real;

  var x,y: wektor;
  var i,n,l,c,r: integer;

  function azymut(p,k:integer; x,y:wektor):real;
  var dx,dy,az: real;
  begin
    dx:=x[k]-x[p];
    dy:=y[k]-y[p];
    IF (dx>0) AND (dy=0) THEN az:=0 ELSE
    IF (dx=0) AND (dy>0) THEN az:=100 ELSE
    IF (dx<0) AND (dy=0) THEN az:=200 ELSE
    IF (dx=0) AND (dy<0) THEN az:=300 ELSE
    IF (dx<>0) AND (dy<>0) THEN
    BEGIN
      az:=arctan(Abs(dy/dx));
      az:=az*200/Pi;
    END;
    IF (dx>0) AND (dy>0) THEN az:=az;
    IF (dx<0) AND (dy>0) THEN az:=200-az;
    IF (dx<0) AND (dy<0) THEN az:=200+az;
    IF (dx>0) AND (dy<0) THEN az:=400-az;
    IF az<0 THEN az:=-az;
    writeln('Azymut wynosi',az:9:4,' gradow');
  end;

  function kat(l,c,r:integer; x,y:wektor):real;
  var azl,azp,a: real;
  begin
    azl:=azymut(l,c,x,y);
    azp:=azymut(r,c,x,y);
    a:=azl-azp;
    writeln('Kat wynosi ',a:9:4,' gradow');
  end;

begin
  writeln('PROGRAM LICZACY FUNKCJE GEODEZYJNE:');
  writeln;

  write('Podaj ilosc punktow: ');
  Readln(n);
  writeln;

  for i:=1 to n do
  begin
    write('Podaj wspolrzedna X',i,': ');
    readln(x[i]);
    write('Podaj wspolrzedna Y',i,': ');
    readln(y[i]);
  end;

  writeln;
  writeln('Obliczanie kata ze wspolrzednych');
  write('Podaj punkt lewy: ');
  readln(l);
  write('Podaj punkt centralny: ');
  readln(c);
  write('Podaj punkt prawy: ');
  readln(r);
  kat(l,c,r,x,y);
  readln;

end.

Program ma w założeniu obliczyć kąt ze współrzędnych. Mój problem pojawia się w 40 linijce ( a:=azl-azp; ), ponieważ w tym momencie powinien odjąć od wartości azymutu lewego wartość azymutu prawego, czego program nie robi i nie mam pojęcia dlaczego.

Zresztą wpiszcie sobie takie dane (wpisywać po kolei, zatwierdzając enterem):
3 0 24 11 25 6 14 3 1 2
Powinno dać kąt równy: 71.3674
A daje 0.0000

0

Mój problem pojawia się w 40 linijce
Nieprawda.

Powinno dać kąt równy: 71.3674
A daje 0.0000
Skoro azl-azp daje 0.0, to znaczy że te wartości są równe. Wyświetl je sobie. Sprawdź którą źle liczy. Być może obie.

0

Obie (tzn. azl i azp) dobrze liczy, sprawdzałem to w innych programach. Jak nie w 40 linijce, to w której?

1

Źle liczysz kąt. Najpierw policzyłeś wartości bezwzględne azymutu. Następnie obliczasz różnicę tych wartości co jest błędem. Należy odjąć od siebie pełne wartości azymutu, nie bezwzględne.

function Azymut(X, Y: Real): Real; // wynik w radianach, -pi .. pi
begin
  Result := ArcTan2(X, Y);
end;

function KatMiedzyWektorami(X1, Y1, X2, Y2: Real): Real; // wynik w radianach, -pi .. pi
begin
  Result := Azymut(X2, Y2) - Azymut(X1, Y1);
  if (Result <= -PI) Result = Result + 2 * PI;
end;
{ ... }
kat := 100 * KatMiedzyWektorami(x[l] - x[c], y[l] - y[c], x[r] - x[c], y[r] - y[c]);
writeln('Kat wynosi ',a:9:4,' gradow');

Aha, jeszcze jedno. Twój typ wektor ma mylącą nazwę, wcale nie reprezentuje tutaj wektora tylko zbiór współrzędnych wielu wektorów (np. zbiór współrzędnych x).

0

Nie wiem czy się znasz na liczeniu azymutów (w sensie, że jesteś geodetą, lub kimś w tym stylu), ale to, co było liczone w wartości bezwzględnej to tzw. czwartak, który jest jednym z etapów liczenia azymutu, więc tam musi być wartość bezwzględna (tak po prostu wynika ze wzoru). Azymut jest dopiero ostatecznie wyliczony w jednym z IF-ów. No i poza tym ja chcę to robić na tablicach.

2

@Ylv, Twój problem polega na tym, że zapomniałeś, iż azymut to jest funkcja i trzeba by gdzieś (zapewne na końcu funkcji) przypisać jej wartość.
Mam rację?

0

Wybacz, że zadam głupie pytanie, ale jak przypisać tą wartość? Jestem kompletnym noobem w tej kwestii, dlatego nie śmiej się ;]

1

UP: Bingo!

Nie trzeba być geodetą aby widzieć jak wyliczyć azymut. To pojęcie jest banalne (kąt między wektorem a osią wskazującą kierunek bazowy np. północ) i nie trzeba wyznaczać żadnych czwartaków.

0

Dzięki @simplex za pomoc, właśnie o to mi chodziło :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1