CODE:
#include
#include
#include
#include
#include
using namespace Linear;
static const double dt = 1.0 / 60;
class Entity
{
public:
virtual void Update() = 0;
virtual void Draw() const = 0;
};
class Particle
: public Entity
{
public :
//質点の作成
static std::shared_ptr Create( double m, Vector s, Vector v )
{
return std::shared_ptr( new Particle(m,s,v) );
}
//質点に力を加える
void AddForce( Vector f )
{
f_ += f;
}
//質点の位置を取得
const Vector S() const
{
return s_;
}
//質点の速度を取得
const Vector V() const
{
return v_;
}
//質点の更新
virtual void Update()
{
//運動方程式に従い加速度、速度、位置を更新
a_ = f_ / m_;
v_ += a_ * dt;
s_ += v_ * dt;
//力を0に
f_ = Vector();
}
virtual void Draw() const
{
DxLib::DrawCircle( s_.x, s_.y, 10, DxLib::GetColor( 0x2C, 0xCC, 0x7c ) );
}
private :
double m_; //質量
Vector s_; //位置
Vector v_; //速度
Vector a_; //加速度
Vector f_; //力
private:
Particle( double m, Vector s, Vector v )
:m_(m),s_(s),v_(v)
{
}
Particle( const Particle& );
Particle& operator=( const Particle& );
};
class Spring
: public Entity
{
public:
//質点の作成
static std::shared_ptr Create( std::weak_ptr p1, std::weak_ptr p2, double k, double l )
{
return std::shared_ptr( new Spring( p1, p2, k, l ) );
}
void Update()
{
auto p1 = p1_.lock();
auto p2 = p2_.lock();
if( p1 && p2 )
{
//質点間の相対位置ベクトルを取得
Vector d = p2->S() - p1->S();
//質点間の距離を算出
double dist = sqrt(double(d*d));
//相対位置ベクトルの単位ベクトルを計算
Vector de = d / dist;
//与える力は大きさk*(dist-l)、向きde
Vector f = de * k_*(dist-l_);
p1->AddForce( f );
p2->AddForce( -f );
}
}
//ばねの描写
void Draw() const
{
auto p1 = p1_.lock();
auto p2 = p2_.lock();
if( p1 && p2 )
{
const int rep = 11;
Vector d = p2->S() - p1->S();
Vector de = d / rep;
d.Normalize();
Vectordn = GetNormalVector2D( d );
dn *= l_ / 10.0;
double xtemp = p1->S().x; double ytemp = p1->S().y;
double orientation = 1;
for( int i = 1; i temp = p1->S()+de*i + dn*orientation;
DxLib::DrawLine( xtemp,ytemp, temp.x, temp.y, 0xFF0000, 1 );
orientation *= -1;
xtemp = temp.x, ytemp = temp.y;
}
DxLib::DrawLine( xtemp,ytemp, p2->S().x, p2->S().y, 0xFF0000, 1 );
}
}
private:
//質点1, 質点2, ばね定数k, ばねの自然長l
Spring( std::weak_ptr p1, std::weak_ptr p2, double k, double l )
:p1_(p1),p2_(p2),k_(k),l_(l)
{
}
std::weak_ptr p1_;
std::weak_ptr p2_;
double k_;
double l_;
};
//質点に毎フレームごとに力を与えるクラス
class Environment
{
public:
static Environment& Instance()
{
static Environment e;
return e;
}
//質点を設定
void SetEntity( std::weak_ptr entity )
{
entities_.push_back(entity);
}
void Update()
{
for( auto it = entities_.begin(); it != entities_.end(); ++it )
{
if( auto p = it->lock() )
{
p->Update();
}
}
}
void Draw()
{
for( auto it = entities_.begin(); it != entities_.end(); ++it )
{
if( auto p = it->lock() )
{
p->Draw();
}
}
}
private:
std::vector> entities_;
private:
Environment(){}
Environment( const Environment& );
Environment& operator=( const Environment& );
};
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
ChangeWindowMode(true);
if( DxLib_Init() ( 350, 100, 0 ), Vector(200,0,0) );
auto p2 = Particle::Create( 0.2, Vector( 250, 100, 0 ), Vector(-200,0,0) );
auto s12 = Spring::Create( p1,p2,5,150 );
Environment::Instance().SetEntity( p1 );
Environment::Instance().SetEntity( p2 );
Environment::Instance().SetEntity( s12 );
//質点2つとばね(質点の初速度の関係で回転する)
auto p3 = Particle::Create( 0.2, Vector( 350, 200, 0 ), Vector(200,70,0) );
auto p4 = Particle::Create( 0.2, Vector( 250, 200, 0 ), Vector(-200,-70,0) );
auto s34 = Spring::Create( p3,p4,5,100 );
Environment::Instance().SetEntity( p3 );
Environment::Instance().SetEntity( p4 );
Environment::Instance().SetEntity( s34 );
//n質点系(質点の初速度の関係で回転する)(カオス的)
auto p5 = Particle::Create( 0.2, Vector( 150, 400, 0 ), Vector(200,70,0) );
auto p6 = Particle::Create( 0.2, Vector( 250, 400, 0 ), Vector(100,70,0) );
auto p7 = Particle::Create( 0.2, Vector( 350, 400, 0 ), Vector(-100,-70,0) );
auto p8 = Particle::Create( 0.2, Vector( 450, 400, 0 ), Vector(-200,-70,0) );
auto s56 = Spring::Create( p5,p6,5,100 );
auto s67 = Spring::Create( p6,p7,10,100 );
auto s78 = Spring::Create( p7,p8,5,100 );
Environment::Instance().SetEntity( p5 );
Environment::Instance().SetEntity( p6 );
Environment::Instance().SetEntity( p7 );
Environment::Instance().SetEntity( p8 );
Environment::Instance().SetEntity( s56 );
Environment::Instance().SetEntity( s67 );
Environment::Instance().SetEntity( s78 );
while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 )
{
ClearDrawScreen() ;
//メインループ
{
Environment::Instance().Update();
Environment::Instance().Draw();
}
ScreenFlip() ;
}
DxLib_End() ;
return 0 ;
}