Działania na wektorach.. problem z kątami nachylenia.

0

Witam.
Zadanie polega na tym:
Program powinien umożliwiać:
• Działania na n wektorach (n=1,..,5),
• Program powinien dawać możliwość: dodawania, odejmowania wektorów oraz wyznaczania ich iloczynów skalarnych, cosinusów kierunkowych, kątów α, β, γ, nachylenia wektora wynikowego względem osi X, Y, Z.

Wrzucam kod:
[code]
program podstawy;
USES CRT;
TYPE
Twektor=record
x : integer;
y : integer;
z : integer;
END;

VAR
wek: array[1..5] of Twektor;
wek_h: array[1..2] of Twektor;
k,l,m,n,o:integer;
p,i,r:byte;
a:char;

PROCEDURE czyt_dane;
BEGIN
writeln('Wprowadz liczbe wektorow <1-5>:');
readln(p);
writeln;
IF (p>=1)AND(p<=5) THEN
BEGIN
FOR i:=1 TO p DO
BEGIN
writeln('Wprowadz wspolrzedna x dla wektora ',i);
readln(k);
wek[i].x:=k;
writeln('Wprowadz wspolrzedna y dla wektora ',i);
readln(l);
wek[i].y:=l;
writeln('Wprowadz wspolrzedna z dla wektora ',i);
readln(m);
wek[i].z:=m;
writeln;
END;
END
ELSE writeln('Liczba wektorow musi byc liczba z przedzialu <1-5>!');
END;

PROCEDURE wyb_wek;
BEGIN
writeln('Program wykona wzkazane dzialanie tylko na dwoch wybranych wektorach.');
writeln('Wprowadz numer pierwszego wektora:');
readln(n);
IF (n>=1)AND(n<=p) THEN
BEGIN
wek_h[1]:=wek[n];
writeln('Wprowadz numer drugiego wektora:');
readln(o);
writeln;
IF (o>=1)AND(o<=p) THEN wek_h[2]:=wek[o]
ELSE writeln('Numer wektora musi byc liczba z przedzialu <1-',p,'>!');
writeln;
END
ELSE writeln('Numer wektora musi byc liczba naturalna z przedzialu <1-',p,'>!');

       END;

FUNCTION dod_wek:integer;
VAR
suma_x,suma_y,suma_z:integer;

    BEGIN
     suma_x:=wek_h[1].x + wek_h[2].x;                                       
     suma_y:=wek_h[1].y + wek_h[2].y;
     suma_z:=wek_h[1].z + wek_h[2].z;
     writeln('Postac wektora wypadkowego sumy wektorow:',suma_x,'i + ',suma_y,'j + ',suma_z,'k');
    END;

FUNCTION od_wek:integer;
VAR
roz_x,roz_y,roz_z:integer;

    BEGIN
     roz_x:=wek_h[1].x - wek_h[2].x;                                         
     roz_y:=wek_h[1].y - wek_h[2].y;
     roz_z:=wek_h[1].z - wek_h[2].z;
     writeln('Postać wektora wypadkowego roznicy wektorow:',roz_x,'i + ',roz_y,'j + ',roz_z,'k');
    END;

FUNCTION ilocz_wek:integer;
VAR
ilocz_x,ilocz_y,ilocz_z:integer;
BEGIN
ilocz_x:=wek_h[1].xwek_h[2].x;
ilocz_y:=wek_h[1].y
wek_h[2].y;
ilocz_z:=wek_h[1].z*wek_h[2].z;
writeln('Postać iloczynu skalarnego wektorow:',ilocz_x,'i + ',ilocz_y,'j + ',ilocz_z,'k');
END;

FUNCTION cos_k:real;
VAR
wyp_x,wyp_y,wyp_z:integer;
cos_x,cos_y,cos_z,alfa,beta,gama,modul:real;

    BEGIN                                                                    
     wyp_x:=wek_h[1].x + wek_h[2].x;
     wyp_y:=wek_h[1].y + wek_h[2].y;
     wyp_z:=wek_h[1].z + wek_h[2].z;
     modul:=sqrt(sqr(wyp_x)+sqr(wyp_y)+sqr(wyp_z));                          
       IF modul<>0 THEN
         BEGIN                                                               
          cos_x:=wyp_x/modul;
          cos_y:=wyp_y/modul;
          cos_z:=wyp_z/modul;

          writeln('Cosinus kierunkowy skladowej x wektora wypadkowego wynosi:',cos_x:6:3);
          writeln('Cosinus kierunkowy skladowej y wektora wypadkowego wynosi:',cos_y:6:3);
          writeln('Cosinus kierunkowy skladowej z wektora wypadkowego wynosi:',cos_z:6:3);
         END
            ELSE writeln('Wypadkowy wektor jest wetorem zerowym!');
    END;

PROCEDURE wybor;
BEGIN
writeln('Wybierz nr. dzialania <1-4>');
writeln('1 - Dodawanie');
writeln('2 - Odejmowanie');
writeln('3 - Iloczyn skalarny');
writeln('4 - Wyznaczanie cosinusow kierunkowych oraz katow nachylenia do osi OX, OY i OZ');
readln(r);
IF r=1 THEN dod_wek;
IF r=2 THEN od_wek;

  IF r=3 THEN ilocz_wek;
  IF r=4 THEN cos_k;
  writeln;
 END;

BEGIN
czyt_dane;
IF (p>=1)AND(p<=5) THEN
BEGIN
REPEAT
clrscr;
wyb_wek;
IF ((n>=1)AND(n<=p))AND((o>=1)AND(o<=p)) THEN wybor;
writeln;
writeln('Jezeli chcesz wykonac jakies dzialanie ponownie, wcisnij " T ", w przeciwnym wypadku wcicnij "N".');
readln(a);
writeln;
UNTIL (a='N')OR(a='p');
END;
readln;
END.

[/code]
A teraz problemy:

  1. Jak ruszyć te kąty nachylenia? Czy ktoś mógłby coś dopisać??
  2. Jażeli program poprosi o wybór dwóch wektorów na których mają przeprowadzone być działania a użytkownik wprowadzi niepoprawne cyfry zostanie wyświetlony komunikat :"Numer wektora musi byc liczba naturalna z przedzialu <1-',p,'>!" ale wypadało by wtedy zeby program wykonywał jakąś pętle i ponownie prosił o wskazania wektorów...No własnie jak to zrobić???

NIGDY NIE MIAłEM DO CZYNIENIA Z PROGRAMOWANIEM!!! NA ZALICZENIE Z MECHANIKI JEDNAK MUSIAłEM NAPISAć TAKIE COś. PROSZę POWSTRZYMAć SIę OD ZGRYźLIWYCH KOMENTARZY PONIEWAż TO MóJ PIERWSZY PROGRAM W żYCIU PISANY W OPOARCIU O KSIążKI I FORA INTERNETOWE.

Z GóRY BARDZO DZIęKUJę ZA POMOC

0

wklejam kilka procedur z mojego silnika 3d.

PROCEDURE VectorLen(VAR a, b : TPunkt; VAR Len : real);
BEGIN
Len := sqrt( (b.x - a.x)*(b.x - a.x) +
             (b.y - a.y)*(b.y - a.y) +
             (b.z - a.z)*(b.z - a.z) );
END; 

PROCEDURE AddVector(VAR a, b, c : TPunkt);
BEGIN
 c.x := a.x + b.x;
 c.y := a.y + b.y;
 c.z := a.z + b.z;
END; 

PROCEDURE SubVector(VAR a, b, c : TPunkt);
BEGIN
 c.x := a.x - b.x;
 c.y := a.y - b.y;
 c.z := a.z - b.z;
END; 

PROCEDURE VectMulReal(VAR a : TPunkt; liczba : real; VAR b : TPunkt);
BEGIN
 b.x := liczba * a.x;
 b.y := liczba * a.y;
 b.z := liczba * a.z;
END; 

PROCEDURE ScalarVector(VAR a, b : TPunkt; VAR wynik : real);
BEGIN
 wynik := a.x*b.x + a.y*b.y + a.z*b.z;
END; 

PROCEDURE MulVector(VAR a, b, c : TPunkt);
BEGIN
 c.x := a.y*b.z - a.z*b.y;
 c.y := a.z*b.x - a.x*b.z;
 c.z := a.x*b.y - a.y*b.x;
END; 

PROCEDURE NormVector(wektor : TPunkt; VAR wynik : TPunkt);
VAR Len : real;
BEGIN
 Len := sqrt((wektor.x * wektor.x) +
             (wektor.y * wektor.y) +
             (wektor.z * wektor.z));
 IF (Len = 0) THEN Len := 1;
 wynik.x := wektor.x / Len;
 wynik.y := wektor.y / Len;
 wynik.z := wektor.z / Len;
END;

Wektor leży na prostej, której równanie można wyliczyć. Kąt nachylenia prostej do wykresu to arctan A owego równania y=Ax+B. Piszesz na zaliczenie z mechaniki, nie mów, że mam wykładać całą terię na temat rzutów sił, podstaw trygonometri i fizyki i konwersji pomiędzy prostokątnym i biegunowym układem współżędnych.

0

Nie nie...teori nie trzeba mi wykładać. Jednak mimo wszystko programowanie to dla mnie kompletna abstrakcja. I tak dziwię się, że tyle tego napisałem. A z tego co wrzuciłeś też niewiele rozumiem niestety...

0

Uproszczenie: Wektor startuje z punktu A(0,0,0) - domyślnie. Następnie podajesz punkt B(X,Y,Z). Mając punkty AB możesz narysować odcinek |AB|. Mając odcinek (nazwijmy go prosta) możesz obliczyć jej równanie y = ax+b (prosta przechodząca przez dwa punkty). Następnie obliczasz arctan(a) i masz podany kąt nachylenia wektora (prostej) do osi x.

0

Fajnie tylko Ty cały czas piszesz mi jak to zrobić co niestety (albo i stety ja wiem). Dla mnie barierą jest jezyk programowania, sposób ubrania tego w kod. Próbowałem jak widać co doprowadziło mnie do takiej postaci mojego programu, a teraz napotkałem ścianę. Więc jeżeli masz chęci to moze skrobnij jak to powinno wyglądać.

0
type
  TPunkt = record
    x, y, z :Single;
  end;

procedure CalcAngle(const pA, pB :TPunkt; var alfa, beta, gamma :single);
var
  coeff :Single;
begin
  coeff := (pB.y - pA.y) / (pB.x - pA.x);
  alfa := (ArcTan(coeff) * 180) / PI; // zamiana radianów na stopnie
  beta := 90-alfa;
  coeff := (pB.Y - pA.y) / (pB.z - pA.z);
  gamma := (ArcTan(coeff) * 180) / PI;
end;

var
  A, B       :TPunkt;
  ka, kb, kg :Single;

begin
 { punkt startu odcinka }
 A.x := 0;
 A.y := 0;
 A.z := 0;

 { punkt końca odcinka  }
 B.x := -2;
 B.y := +2;
 B.z := +2;

 CalcAngle(A, B, ka, kb, kg);
 WriteLn('ka: ', ka:0:2);
 WriteLn('kb: ', kb:0:2);
 WriteLn('kg: ', kg:0:2);
 ReadLn;
end.
0

Naprawdę setne dzięki. Jeszcze tylko teraz powiedz mi w którym miejscu to umieścić. Gdybym kiedyś mógł ci jakoś pomóc to wal jak w dym [browar] [soczek]

0
{
Przemieniłem twoją funkcję na procedurę.
Nie sprawdzałem wszystkich warunków, kąty masz obliczone.
Cosinusy wyciągnij sobie jak chcesz (to już proste)
Zastąp kod <b>cos_k</b> na mój.

Uwaga: moja deklaracja TPunkt różni się od Twojej TWektor. Poprzerabiaj dla ujednolicenia typów.
}
procedure cos_k; 
var ka, kb, kg :Single;
begin
 CalcAngle(wek_h[1], wek_h[2], ka, kb, kg);
  
 Writeln('alfa: ',ka:6:3);
 Writeln('beta: ',kb:6:3);
 Writeln('gamma: ',kg:6:3);
end;

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