最後に三次元極座標に苦労しました。
θとかφとか軸とかなんかもうわけわかめ。
そんな苦労の結晶(?)がこちらです。
[nico]http://www.nicovideo.jp/watch/sm16271112[/nico]
これであんなエフェクトやこんなエフェクトが作り放題・・・
なのか?
そんなわけで見にくいコードはこちら。
ファイル分割しないと長い・・・。
► スポイラーを表示
#include "DxLib.h"
#include
#include
using namespace std;
#define SCREEN_MAX_Y 480
#define PI 3.141592654
class vector2D
{
public:
double x;
double y;
vector2D()
{
x=0;
y=0;
}
};
class Cbreakglass
{
public:
double minx; //分割し始めのx座標
double miny;
double maxx; //分割し終わりのx座標
double maxy;
int graph;
int width; //画像を2^nにするときの1辺の長さ
Cbreakglass()
{
minx=0;
miny=0;
maxx=640;
maxy=480;
width=0;
}
//割れる範囲を指定(最初に行う)
void setbox(double minX,double minY,double maxX,double maxY);
//画像を2^nの画像に張り付ける
void make_squaregraph(int handle);
//2点から画像を分割する。2点は他の点と同じ座標でなく、かつx,yのどちらかが必ずminx,maxx,miny,maxyのいずれかであり、しかも2点は同じ辺上にあってはいけない
void split_multiangle(vector2D v[]);
};
Cbreakglass glass;
//割れる範囲を指定(最初に行う)
void Cbreakglass::setbox(double minX,double minY,double maxX,double maxY)
{
minx=minX;
miny=minY;
maxx=maxX;
maxy=maxY;
}
//画像を2^nの画像に張り付ける
void Cbreakglass::make_squaregraph(int handle)
{
//幅を2^nにする作業
if(maxx-minx > maxy-miny)
width=int(maxx-minx);
else
width=int(maxy-miny);
int min=1;
int max=2;
for(int i=0; i min && width x=x;
this->y=y;
this->z=z;
this->theta=theta;
this->phi=phi;
}
void Cobj3D::move_mf()
{
if(Flag>0)
{
x+=vx;
y+=vy;
z+=vz;
theta+=vtheta;
phi+=vphi;
}
}
//多角形を扱うクラス
class Cmultiangle
{
public:
int angle; //何角形か表す。0なら未登録
vector tyoten; //頂点座標
Cobj3D jyusin; //重心情報
vector t_range; //重心から頂点までの距離
vector t_kacdo; //重心から頂点までの角度
Cmultiangle()
{
angle=0;
}
void set(int angle,vector2D pos[])
{
this->angle=angle;
for(int i=0; i multiangle;
void Cmultiangle::setjyusin() //頂点座標から重心の情報をセット
{
vector2D g;
for(int i=0; i x=x;
pv->y=y;
return 0;
}
else
return 1;
}
//線を一本引く(辺上の2点を決定) その2点の座標を引数に代入
void makeline(vector2D v[])
{
int oldnum=-1; //前のと同じ辺上に線を引かないように
//辺上の2点を決定
for(int i=0; i 2)
{
for(int j=0; j 0) //この値が正ならこれから更新する多角形は小さい方
miniFlag=TRUE;
if(hen_distance > multiangle[i].angle/2) //ぐるっと回りこんでる場合は短い方にする
hen_distance=multiangle[i].angle-hen_distance;
Cmultiangle tmpangle=multiangle[i]; //分割前の多角形データを保存
//まず既存の多角形データの更新
if(miniFlag==TRUE)
multiangle[i].angle=hen_distance+2;
else
multiangle[i].angle=tmpangle.angle-hen_distance+2;
multiangle[i].tyoten.clear(); //頂点情報破棄
for(int k=0; k 2)
{
multiangle[i].setjyusin();
}
}
glass.make_squaregraph(GrHandle);
int count=0;
while(ProcessMessage()==0 && ClearDrawScreen()==0 && CheckHitKey(KEY_INPUT_ESCAPE)==0) //ここからループ
{
if(count>100)
{
for(int i=0; i 2)
{
multiangle[i].jyusin.vy -= 0.1; //重力
multiangle[i].jyusin.move_mf();
}
}
}
for(int i=0; i 2)
{
multiangle[i].draw();
}
}
/*
//線分描画
int c1=GetColor(0,255,255);
for(int i=0; i 2)
{
int num=multiangle[i].angle;
for(int j=0; j 2)
{
int num=multiangle[i].angle;
for(int j=0; j 0)
Sleep(16-term);
t=GetNowCount();
return;
}
//(x1,y1),(x2,y2)を通る直線と(x3,y3),(x4,y4)を通る直線の交点を取得し、線分の当たり判定をする
int senbun_senbun_hitnot(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4,vector2D* v)
{
if(x3==x4) //図形の線分が縦線かつその間から線分が伸びている場合
{
if(x3==x1)
{
if((y1-y3)*(y1-y4)x=x1;
v->y=y1;
return 1;
}
else
return 0;
}
else if(x3==x2)
{
if((y2-y3)*(y2-y4)x=x2;
v->y=y2;
return 1;
}
else
return 0;
}
}
if(y3==y4) //図形の線分が横線かつその間から線分が伸びている場合
{
if(y3==y1)
{
if((x1-x3)*(x1-x4)x=x1;
v->y=y1;
return 1;
}
else
return 0;
}
else if(y3==y2)
{
if((x2-x3)*(x2-x4)x=x2;
v->y=y2;
return 1;
}
else
return 0;
}
}
double bunbo=(x4-x3)*(y2-y1)-(x2-x1)*(y4-y3);
if(bunbo!=0)
v->x= (x1*(x4-x3)*(y2-y1)-x3*(x2-x1)*(y4-y3)+(x2-x1)*(x4-x3)*(y3-y1))/bunbo;
else
v->x=999999;
bunbo=(y4-y3)*(x2-x1)-(y2-y1)*(x4-x3);
if(bunbo!=0)
v->y= (y1*(y4-y3)*(x2-x1)-y3*(y2-y1)*(x4-x3)+(y2-y1)*(y4-y3)*(x3-x1))/bunbo;
else
v->y=999999;
if((v->x -x1)*(v->x -x2)y -y1)*(v->y -y2)x -x3)*(v->x -x4)y -y3)*(v->y -y4)<=0) //線分の間に交点があるかを調べる
return 1;
else
return 0;
}