RSS

Jumat, 01 Oktober 2010

Pembuatan AI dengan implementasi C++ (part 2)

Setelah kemarin kita bahas tentang komponen dasar pembuatan AI sekarang kita langsung terjun ke pemrogramannya...Seperti yang sudah dikatakan sebelumnya bahwa untuk membuat sebuah game kita membutuhkan basic matematika dan fisika yang kuat terutama untuk vektor (lihat kembali buku aljabar liniernya..) saya akan beri satu contoh file header untuk vektor 2d...
Untuk membuat projectnya buka visual studio - new - project - pilih visual c++ -pilih win32 project - pilih windows application...
disitu sudah tersedia contoh untuk windows application dasar (kita dapat merubahnya nanti) silahkan tekan f5 untuk melihat menu windownya...

Lalu di menu solution explorer klik kanan - add - header file - tuliskan namanya menjadi Vector2D.h...

sudah?

nah sekarang kita harus menuliskan kode program untuk semua operasi vector yang nantinya akan dipakai untuk menggambar lapangan, pergerakan pemain, dan pergerakan bola...

Vector2D.h

#ifndef VECTOR2D_H
#define VECTOR2D_H

#include
#include
#include
#include
#include "utils.h" //tar dibuat file header utils.h

struct Vector2D
{
double x;
double y;

Vector2D(): x(0,0), y(0,0){} // ctor tanpa parameter
Vector2D(double a, double b) : x(a),y(b){} // ctor dengan parameter

void Nol() {x=0,0; y=0,0;}

bool isNol()const {return (x*x + y*y)< MinDouble;} // nah MinDouble itu nanti ada di utils.h

inline double Length()const;

inline double Lengthsq()const; // bedanya klo Lengthsq tanpa pke sqrt (akar)

inline void Normalize();

inline double Dot(const Vector2D& v2)const;

inline int Sign(const Vector2D& v2)const; // Vektor memiliki arah, tujuannya untuk
//Menentukan arah vektor positif atau negatif

inline Vector2D Perp()const;

inline void Truncate(double max);

//Jarak antara vektor
inline double Distance(const Vector2D &v2)const;

//akarkan Vektor diatas.
inline double DistanceSq(const Vector2D &v2)const;

inline void Reflect(const Vector2D& norm);

//kembalikan nilai vektor yang direverse
inline Vector2D GetReverse()const;


//Overload operator
const Vector2D& operator+=(const Vector2D &rhs)
{
x += rhs.x;
y += rhs.y;

return *this;
}

const Vector2D& operator-=(const Vector2D &rhs)
{
x -= rhs.x;
y -= rhs.y;

return *this;
}

const Vector2D& operator*=(const double& rhs)
{
x *= rhs;
y *= rhs;

return *this;
}

const Vector2D& operator/=(const double& rhs)
{
x /= rhs;
y /= rhs;

return *this;
}

bool operator==(const Vector2D& rhs)const
{
return (isEqual(x, rhs.x) && isEqual(y,rhs.y) );
}

bool operator!=(const Vector2D& rhs)const
{
return (x != rhs.x) || (y != rhs.y);
}

};

//---------------------------------------------------beberapa overload operator
inline Vector2D operator*(const Vector2D &lhs, double rhs);
inline Vector2D operator*(double lhs, const Vector2D &rhs);
inline Vector2D operator-(const Vector2D &lhs, const Vector2D &rhs);
inline Vector2D operator+(const Vector2D &lhs, const Vector2D &rhs);
inline Vector2D operator/(const Vector2D &lhs, double val);
std::ostream& operator<<(std::ostream& os, const Vector2D& rhs);
std::ifstream& operator>>(std::ifstream& is, Vector2D& lhs);


//------------------------------------------------------------------------Fungsi member

//------------------------- Length ---------------------------------------
//
// returns the length of a 2D vector
//------------------------------------------------------------------------
inline double Vector2D::Length()const
{
return sqrt(x * x + y * y);
}


//------------------------- LengthSq -------------------------------------
//
// returns the squared length of a 2D vector
//------------------------------------------------------------------------
inline double Vector2D::LengthSq()const
{
return (x * x + y * y);
}


//------------------------- Vec2DDot -------------------------------------
//
// calculates the dot product
//------------------------------------------------------------------------
inline double Vector2D::Dot(const Vector2D &v2)const
{
return x*v2.x + y*v2.y;
}

//------------------------ Sign (penanda positif atau negatif----------------------------------
//
// Positif jika vektor searah jarum jam,
// negatif jika vektor berlawanan arah jarum jam (Y axis kebawah, X axis to kanan)
//------------------------------------------------------------------------
enum {clockwise = 1, anticlockwise = -1};

inline int Vector2D::Sign(const Vector2D& v2)const
{
if (y*v2.x > x*v2.y)
{
return anticlockwise;
}
else
{
return clockwise;
}
}

//------------------------------ Perpendicular ------------------------------------
//
// Prependicular vektor
//------------------------------------------------------------------------
inline Vector2D Vector2D::Perp()const
{
return Vector2D(-y, x);
}

//------------------------------ Distance --------------------------------
//
// calculates the euclidean distance between two vectors
//------------------------------------------------------------------------
inline double Vector2D::Distance(const Vector2D &v2)const
{
double ySeparation = v2.y - y;
double xSeparation = v2.x - x;

return sqrt(ySeparation*ySeparation + xSeparation*xSeparation);
}


//------------------------------ DistanceSq (jarak tanpa sqrt) ------------------------------
//
// calculates the euclidean distance squared between two vectors
//------------------------------------------------------------------------
inline double Vector2D::DistanceSq(const Vector2D &v2)const
{
double ySeparation = v2.y - y;
double xSeparation = v2.x - x;

return ySeparation*ySeparation + xSeparation*xSeparation;
}

//----------------------------- Truncate (pemotongan) ---------------------------------
//
// truncates a vector so that its length does not exceed max
//------------------------------------------------------------------------
inline void Vector2D::Truncate(double max)
{
if (this->Length() > max)
{
this->Normalize();

*this *= max;
}
}


//---------------------------REFLEKSI -------------------------------------
inline void Vector2D::Reflect(const Vector2D& norm)
{
*this += 2.0 * this->Dot(norm) * norm.GetReverse();
}

//----------------------- REVERSE ----------------------------------------
//
// returns the vector that is the reverse of this vector
//------------------------------------------------------------------------
inline Vector2D Vector2D::GetReverse()const
{
return Vector2D(-this->x, -this->y);
}


//------------------------- Normalize ------------------------------------
//
// normalizes a 2D Vector
//------------------------------------------------------------------------
inline void Vector2D::Normalize()
{
double vector_length = this->Length();

if (vector_length > std::numeric_limits::epsilon())
{
this->x /= vector_length;
this->y /= vector_length;
}
}


//------------------------------------------------------------------------Fungsi yang bukan //member vektor

inline Vector2D Vec2DNormalize(const Vector2D &v)
{
Vector2D vec = v;

double vector_length = vec.Length();

if (vector_length > std::numeric_limits::epsilon())
{
vec.x /= vector_length;
vec.y /= vector_length;
}

return vec;
}


inline double Vec2DDistance(const Vector2D &v1, const Vector2D &v2)
{

double ySeparation = v2.y - v1.y;
double xSeparation = v2.x - v1.x;

return sqrt(ySeparation*ySeparation + xSeparation*xSeparation);
}

inline double Vec2DDistanceSq(const Vector2D &v1, const Vector2D &v2)
{

double ySeparation = v2.y - v1.y;
double xSeparation = v2.x - v1.x;

return ySeparation*ySeparation + xSeparation*xSeparation;
}

inline double Vec2DLength(const Vector2D& v)
{
return sqrt(v.x*v.x + v.y*v.y);
}

inline double Vec2DLengthSq(const Vector2D& v)
{
return (v.x*v.x + v.y*v.y);
}


inline Vector2D POINTStoVector(const POINTS& p)
{
return Vector2D(p.x, p.y);
}

inline Vector2D POINTtoVector(const POINT& p)
{
return Vector2D((double)p.x, (double)p.y);
}

inline POINTS VectorToPOINTS(const Vector2D& v)
{
POINTS p;
p.x = (short)v.x;
p.y = (short)v.y;

return p;
}

inline POINT VectorToPOINT(const Vector2D& v)
{
POINT p;
p.x = (long)v.x;
p.y = (long)v.y;

return p;
}



// Overload Operator
inline Vector2D operator*(const Vector2D &lhs, double rhs)
{
Vector2D result(lhs);
result *= rhs;
return result;
}

inline Vector2D operator*(double lhs, const Vector2D &rhs)
{
Vector2D result(rhs);
result *= lhs;
return result;
}

//overload the - operator
inline Vector2D operator-(const Vector2D &lhs, const Vector2D &rhs)
{
Vector2D result(lhs);
result.x -= rhs.x;
result.y -= rhs.y;

return result;
}

//overload the + operator
inline Vector2D operator+(const Vector2D &lhs, const Vector2D &rhs)
{
Vector2D result(lhs);
result.x += rhs.x;
result.y += rhs.y;

return result;
}

//overload the / operator
inline Vector2D operator/(const Vector2D &lhs, double val)
{
Vector2D result(lhs);
result.x /= val;
result.y /= val;

return result;
}

///////////////////////////////////////////////////////////////////////////////



inline void WrapAround(Vector2D &pos, int MaxX, int MaxY)
{
if (pos.x > MaxX) {pos.x = 0.0;}

if (pos.x < 0) {pos.x = (double)MaxX;}

if (pos.y < 0) {pos.y = (double)MaxY;}

if (pos.y > MaxY) {pos.y = 0.0;}
}


inline bool NotInsideRegion(Vector2D p,
Vector2D top_left,
Vector2D bot_rgt)
{
return (p.x <> bot_rgt.x) ||
(p.y <> bot_rgt.y);
}

inline bool InsideRegion(Vector2D p,
Vector2D top_left,
Vector2D bot_rgt)
{
return !((p.x <> bot_rgt.x) ||
(p.y <> bot_rgt.y));
}

inline bool InsideRegion(Vector2D p, int left, int top, int right, int bottom)
{
return !( (p.x <> right) || (p.y <> bottom) );
}


inline bool isSecondInFOVOfFirst(Vector2D posFirst,
Vector2D facingFirst,
Vector2D posSecond,
double fov)
{
Vector2D toTarget = Vec2DNormalize(posSecond - posFirst);

return facingFirst.Dot(toTarget) >= cos(fov/2.0);
}





#endif
}

-bingung? baca lagi Pengantar C++ nya....
-Kenapa menggunakan C++ ? karena dia full support untuk OOP...
-beberapa operasi vektor pada kode diatas adalah jumlah operasi vektor yang sebenarnya (aljabar linear lanjutan)

1 komentar:

  1. wah.. skripsi nya udah jauh melejit..

    di atas ada 4 kali #include tp gk ada lanjutannya..
    Sebenarnya apa yang dilakukan oleh #include tersebut??

    BalasHapus