pomocy z funkcją acosf

pomocy z funkcją acosf
wilkwielki
  • Rejestracja:ponad rok
  • Ostatnio:około godziny
  • Postów:427
0
Kopiuj
#ifndef __VECTOR_H
#define __VECTOR_H

#include <math.h>

/*
     VECTOR.H

     scalar_t
     CVector 

     
     Copyright (c) 2000 Bas Kuenen. 
     baskuenen.cfxweb.net
*/

typedef float scalar_t;  // skalar


// klasa CVector
// specjalne podziękowania dla Basa Kuenena za koncepcje wykorzystania operatorów

class CVector
{
public:
     scalar_t x;
     scalar_t y;
     scalar_t z;    // składowe x,y,z 

public:
     // konstruktor
     CVector(scalar_t a = 0, scalar_t b = 0, scalar_t c = 0) : x(a), y(b), z(c) {}
     CVector(const CVector &vec) : x(vec.x), y(vec.y), z(vec.z) {}

     // podstawienie wektora
     const CVector &operator=(const CVector &vec)
     {
          x = vec.x;
          y = vec.y;
          z = vec.z;

          return *this;
     }

     // równość wektorów
     const bool operator==(const CVector &vec) const
     {
          return ((x == vec.x) && (y == vec.y) && (z == vec.z));
     }

     // nierówność wektorów
     const bool operator!=(const CVector &vec) const
     {
          return !(*this == vec);
     }

     // dodawanie wektorów
     const CVector operator+(const CVector &vec) const
     {
          return CVector(x + vec.x, y + vec.y, z + vec.z);
     }

     // dodawanie wektorów
     const CVector operator+() const
     {    
          return CVector(*this);
     }

     // dodawanie wektorów
     const CVector& operator+=(const CVector& vec)
     {    x += vec.x;
          y += vec.y;
          z += vec.z;
          return *this;
     }

     // odejmowanie wektorów
     const CVector operator-(const CVector& vec) const
     {    
          return CVector(x - vec.x, y - vec.y, z - vec.z);
     }
     
     // odejmowanie wektorów
     const CVector operator-() const
     {    
          return CVector(-x, -y, -z);
     }

     // odejmowanie wektorów
     const CVector &operator-=(const CVector& vec)
     {
          x -= vec.x;
          y -= vec.y;
          z -= vec.z;

          return *this;
     }

     // mnożenie wektora przez skalar
     const CVector &operator*=(const scalar_t &s)
     {
          x *= s;
          y *= s;
          z *= s;
          
          return *this;
     }

     // dzielenie wektora przez skalar
     const CVector &operator/=(const scalar_t &s)
     {
          const float recip = 1/s; // dla efektywności

          x *= recip;
          y *= recip;
          z *= recip;

          return *this;
     }

     // mnożenie wektora przez skalar
     const CVector operator*(const scalar_t &s) const
     {
          return CVector(x*s, y*s, z*s);
     }

     // mnożenie wektora przez skalar
     friend inline const CVector operator*(const scalar_t &s, const CVector &vec)
     {
          return vec*s;
     }

/*   friend inline const CVector operator*(const CVector &vec, const scalar_t &s)
     {
          return CVector(vec.x*s, vec.y*s, vec.z*s);
     }

*/   // dzielenie wektora przez skalar
     const CVector operator/(scalar_t s) const
     {
          s = 1/s;

          return CVector(s*x, s*y, s*z);
     }

     // iloczyn wektorowy
     const CVector CrossProduct(const CVector &vec) const
     {
          return CVector(y*vec.z - z*vec.y, z*vec.x - x*vec.z, x*vec.y - y*vec.x);
     }

     // iloczyn wektorowy
     const CVector operator^(const CVector &vec) const
     {
          return CVector(y*vec.z - z*vec.y, z*vec.x - x*vec.z, x*vec.y - y*vec.x);
     }

     // iloczyn skalarny
     const scalar_t DotProduct(const CVector &vec) const
     {
          return x*vec.x + y*vec.x + z*vec.z;
     }

     // iloczyn skalarny
     const scalar_t operator%(const CVector &vec) const
     {
          return x*vec.x + y*vec.x + z*vec.z;
     }


     // długość wektora
     const scalar_t Length() const
     {
          return (scalar_t)sqrt((double)(x*x + y*y + z*z));
     }

     // wektor jednostkowy
     const CVector UnitVector() const
     {
          return (*this) / Length();
     }

     // normalizacja wektora
     void Normalize()
     {
          (*this) /= Length();
     }

// operator modułu (długości) wektora
     const scalar_t operator!() const
     {
          return sqrtf(x*x + y*y + z*z);
     }

     // zmienia długość wektora
     const CVector operator | (const scalar_t length) const
     {
          return *this * (length / !(*this));
     }

     // zmienia długość wektora
     const CVector& operator |= (const float length)
     {
          return *this = *this | length;
     }

     // zwraca kąt, który tworzą wektory
     const float inline Angle(const CVector& normal) const
     {
          return acosf(*this % normal);
     }

     // tworzy odbicie wektora względem powierzchni zdefiniowanej przez normalną
     const CVector inline Reflection(const CVector& normal) const
     {    
          const CVector vec(*this | 1);     // normalizuje wektor
          return (vec - normal * 2.0 * (vec % normal)) * !*this;
     }

};

#endif

a mianowicie chodzi o funkcje Angle która zwraca kąt pomiedzy dwoma wektorami

Kopiuj
   const float inline Angle(const CVector& normal) const
     {
          return acosf(*this % normal);
     }

moze ktos to rozipisać mi po ludzku po nie łapie tego systemu skrótowego liczenia kąta, samymi zmiennymi jesli mozna ... ?
ja wiem to moja wina brak znajomości lepszej języka C++
EDIT; to jest chyba DOT dwojga wektorów ale nie jestem pewien

edytowany 2x, ostatnio: wilkwielki
SL
Kurde, to liberalne użycie operatorów to takie wczesne lata 2000, gdzie programiści jeszcze nie wiedzieli, że się nie da tego czytać xd
DA
  • Rejestracja:prawie 3 lata
  • Ostatnio:2 dni
  • Postów:84
0

Na moim leciwym g++ kompiluje się poprawnie, nawet bez warningów. Z tą funkcją jak w trygonometrii większości, że jest przeznaczana do obliczania na jakimś zakresie liczbowym, jeżeli dostanie jakieś nieprawidłowe dane wywala błąd.

lion137
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 5 godzin
  • Postów:4944
2

Kąt jest inaczej liczony:
cos^-1 * (v * w / |v| * |w|)
Czyli musisz tam dodać jeszcze powyższą normalizację:

Kopiuj
   const float inline Angle(const CVector& normal) const
     {
          return acosf((*this % normal) / (!(*this) * !normal);
     }

Wypadało by też zadbać o stabilność numeryczną, dzielenie przez zero, etc...


wilkwielki
  • Rejestracja:ponad rok
  • Ostatnio:około godziny
  • Postów:427
0

przepraszam ale ja nie rozumiem tej fizyki argumentalowej cos^-1 * (v * w / |v| * |w|) mozna łatwiej na czystych zmiennych tzn tak był bym wstanie zrozumieć
v i w to są wektory i trzeba parametryczne przemnożyć przez siebie czy tak?
a |V| i |W| to długość tych wektorów czy tak?
tylko co dalej nie rozumiem, przepraszam

lion137
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 5 godzin
  • Postów:4944
2

Kat między wektorami to arccos iloczynu skalarnego wektorów podzielonego przez iloczyn ich długości; w kodzie to dodatkowe dzielenie:
/ (!(*this) * !normal)


wilkwielki
  • Rejestracja:ponad rok
  • Ostatnio:około godziny
  • Postów:427
0

chodzi o takie coś:

Kopiuj
float wx,wy,vx,vy,xout,yout;
xout=wx*vx;
yout=wy*vy;

float lenght=sqrt(xout*xout+yout*yout)
xout=xout/lenght;
yout=yout/lenght;
float t=xout*xout+yout*yout
float angle=acosf(t);

jeśli źle to prosze o poprawkę jeśłi mozna?
chyba tak:

Kopiuj
float wx,wy,vx,vy,out;
out=wx*vx+wy*vy;

float lenght=sqrt(out*out)
out=out/lenght;
float angle=acosf(out);

dobrze?

edytowany 2x, ostatnio: wilkwielki
lion137
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 5 godzin
  • Postów:4944
0

Nie wiem co tu robisz, ma dzialac tak samo jak Angle ktora wkleilem.


wilkwielki
  • Rejestracja:ponad rok
  • Ostatnio:około godziny
  • Postów:427
0

próbuje to rozpisać tylko tyle , proste ....

MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:minuta
4

acos przyjmuje wartości z zakresu [-1, 1].
Jedna z defunicji iloczynu skalarnego:
\vec a \cdot \vec b = | \vec a | |\vec b | cos(\alpha)
Ergo, by policzyć kąt potrzebujesz:
\alpha = acos \left(\frac{\vec a \cdot \vec b}{| \vec a | |\vec b |}\right)
Ergo ta twoja linijka float lenght=sqrt(out*out) jest bezsensu.

Rozpisując wartość bezwzględną:
\alpha = acos \left(\frac{\vec a \cdot \vec b}{\sqrt{\vec a \cdot \vec a}\sqrt{\vec b \cdot \vec b}}\right)


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
Marius.Maximus
@MarekR22 na jasnym motywie widać lepiej Twoj wpis
MarekR22
Niedoróbka forum. Użyłem <tex>, więc w ciemnym motywie powinno renderować inaczej. względnie wygenerowany obrazek ze wzorem powinien mieć białe tło, a nie przezroczyste.
wilkwielki
  • Rejestracja:ponad rok
  • Ostatnio:około godziny
  • Postów:427
0

dzięki sprawdze ....
mam pytanie te dwa pierwiastki pod kreską to należy je dodać czy przemnożyć?

edytowany 1x, ostatnio: wilkwielki
Althorion
Moderator C/C++
  • Rejestracja:prawie 10 lat
  • Ostatnio:około 17 godzin
  • Postów:1607
3

Oczywiście, że przemnożyć… Pominięcie operacji oznacza mnożenie, nigdy dodawanie — np. 2x to zawsze 2*x, nigdy 2+x.

edytowany 1x, ostatnio: Althorion
wilkwielki
  • Rejestracja:ponad rok
  • Ostatnio:około godziny
  • Postów:427
0

dzięki ...

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.