コード:
#include "DxLib.h"
#include <math.h>
#include <vector>
namespace fw{
typedef unsigned int uint;
template<typename X>
class vector;
template<typename X>
class vecmemdata{
const fw::vector<X> & wvec;
fw::vector<X> & rvec;
bool rflag;
uint mybeg;
uint mynum;
public:
vecmemdata(const fw::vector<X> & target, uint num) :wvec(target) {
mybeg = 0;
mynum = num;
rflag = false;
}
vecmemdata(const fw::vector<X> & target, uint beg, uint num) :wvec(target) {
mybeg = beg;
mynum = num;
rflag = false;
}
vecmemdata(fw::vector<X> & target, uint num) :rvec(target) :rvec(target) {
mybeg = 0;
mynum = num;
rflag = true;
}
vecmemdata(fw::vector<X> & target, uint beg, uint num) :rvec(target) {
mybeg = beg;
mynum = num;
rflag = true;
}
const fw::vector<X> & cvec() const {
if(rflag) return rvec;
return wvec;
}
fw::vector<X> & vec() const { return rvec; }
uint beg() const { return mybeg; }
uint num() const { return mynum; }
const void * cbegress() const {
if(rflag) return &(rvec[beg]);
return &(wvec[beg]);
}
void * begress() const { return &(rvec[beg]); }
};
template<typename X>
class vector{
X * cont[2];
bool use;
uint Size;
uint sized;
uint space;
int Perm;
std::vector<X> myvec;
void mysecure(uint size){
cont[!use] = (X*)malloc(sizeof(X)*size);
for(uint i=0;i<Size;i++) new(&cont[!use][i]) X(cont[use][i]);
for(uint i=0;i<sized;i++) cont[use][i].~X();
free(cont[use]);
use = !use;
space = size;
}
void myset(){
myvec.resize(Size);
for(uint i=0;i<Size;i++) myvec[i] = show(i);
}
void myinit(uint size){
Size = size;
sized = Size;
Perm = 0;
space = size+256;
use = (bool)0;
cont[use] = (X*)malloc(sizeof(X)*space);
}
X & aconss(uint index) const {
uint needSize = index+1;
if(needSize<1 || Size<needSize){
#ifdef FW_VECTOR_POP_UP_
MessageBox(NULL, "範囲外アクセスが発生しました", "エラー", MB_OK);
#endif
throw std::out_of_range("範囲外アクセスエラー");
}
return cont[use][index];
}
public:
void init(uint size=0){
myinit(size);
for(uint i=0;i<size;i++) new(&cont[use][i]) X();
}
void init(const X* arr, uint size){
myinit(size);
for(uint i=0;i<size;i++) new(&cont[use][i]) X(arr[i]);
}
void init(const fw::vector<X> & input){
uint size = input.size();
myinit(size);
for(uint i=0;i<size;i++) new(&cont[use][i]) X(input[i]);
}
vector(){ init(); }
vector(uint size){ init(size); }
vector(const X* arr, uint size){ init(arr, size); }
vector(const fw::vector<X> & input){ init(input); }
fw::vector<X> & operator= (const std::vector<X> & sv){
setsize(sv.size() );
for(uint i=0;i<sv.size();i++) cont[use][i] = sv[i];
return *this;
}
fw::vector<X> & operator= (const fw::vector<X> & fv){
setsize(fv.size() );
for(uint i=0;i<fv.size();i++) cont[use][i] = fv[i];
return *this;
}
fw::vector<X> & operator= (const X & input){
setsize(1);
last() = input;
return *this;
}
operator std::vector<X> (){
myset();
return myvec;
}
operator std::vector<X> & (){
myset();
return myvec;
}
fw::vector<X> & reflect(){
this=myvec;
}
fw::vector<X> & perm(){
Perm = -1;
return *this;
}
fw::vector<X> & perm(uint limit){
Perm = limit;
return *this;
}
fw::vector<X> & lim(){
Perm = 0;
return *this;
}
fw::vector<X> & secure(uint size){
if(Size > size) Size = size;
mysecure(size);
sized = Size;
return *this;
}
fw::vector<X> & requre(uint size){
if(size > space) secure(size);
return *this;
}
fw::vector<X> & addcure(uint size){
requre(Size+size);
return *this;
}
fw::vector<X> & setsize(uint size){
uint reqsize = size;
uint needsize = size;
if(needsize > space){
needsize = reqsize*2;
mysecure(needsize);
}
if(needsize > Size){
for(uint i=Size;i<sized;i++) cont[use][i] = X();
for(uint i=sized;i<reqsize;i++) new(&cont[use][i]) X();
}
Size = reqsize;
if(sized < Size) sized = Size;
return *this;
}
fw::vector<X> & reqsize(uint size){
if(Size < size) setsize(size);
return *this;
}
fw::vector<X> & addsize(uint size=1){
setsize(size+Size);
return *this;
}
fw::vector<X> & popsize(uint size=1){
int ressize = Size - size;
if(ressize < 0) ressize = 0;
setsize(ressize);
return *this;
}
fw::vector<X> & pop(uint size=1){
Size -= size;
return *this;
}
fw::vector<X> & operator-- (){
Size--;
return *this;
}
fw::vector<X> operator-- (int){
fw::vector<X> send = *this;
Size--;
return send;
}
fw::vector<X> & add(){
addsize();
return *this;
}
fw::vector<X> & add(const X & input){
next() = input;
return *this;
}
fw::vector<X> & add(const X * arr, uint size){
requre(Size+size);
for(uint i=0;i<size;i++) next() = arr[i];
return *this;
}
fw::vector<X> & add(const fw::vector<X> & input){
requre(input.size()+Size);
for(uint i=0;i<input.size();i++) next() = input[i];
return *this;
}
fw::vector<X> & operator++ (){
add();
return *this;
}
fw::vector<X> operator++ (int){
fw::vector<X> send = *this;
add();
return send;
}
fw::vector<X> & operator+= (const X & input){
add(input);
return *this;
}
fw::vector<X> & operator+= (const fw::vector<X> & input){
add(input);
return *this;
}
fw::vector<X> & operator<< (const X & input){
add(input);
return *this;
}
fw::vector<X> & operator<< (const fw::vector<X> & input){
add(input);
return *this;
}
const X & access(uint index) const { return aconss(index); }
X & access(uint index){
uint needSize = index+1;
if(needSize >= 1){
if( (int)needSize<=Perm || Perm==-1) reqsize(needSize);
}
return aconss(index);
}
const X & operator[] (uint index) const { return access(index); }
X & operator[] (uint index){ return access(index); }
const X & last() const { return access(Size-1); }
X & last(){ return access(Size-1); }
X & next(){
addsize();
return last();
}
X & next(const X & input){
add(input);
return last();
}
const X * address(uint index) const { return &access(index); }
X * address(uint index){ return &access(index); }
fw::vector<X> member(uint index, uint size) const {
fw::vector<X> r(&access(index), size);
return r;
}
fw::vecmemdata<X> vecmem(uint beg, uint num) const {
fw::vecmemdata<X> v(*this, beg, num);
return v;
}
fw::vecmemdata<X> vecmem(uint num) const {
fw::vecmemdata<X> v(*this, num);
return v;
}
uint size() const { return Size; }
const X * head() const { return address(0); }
X * head(){ return address(0); }
fw::vector<X> operator+ (const X & target){
fw::vector<X> send = *this;
send.add(target);
return send;
}
fw::vector<X> operator+ (const fw::vector<X> & target){
fw::vector<X> send = *this;
send.add(target);
return send;
}
~vector(){
for(uint i=0;i<sized;i++) cont[use][i].~X();
free(cont[use]);
}
};
double inline decimal(double num){ return modf(num, (double *)NULL); }
int inline floor(double num){ return (int)::floor(num); }
int inline integer(double num){
double i;
modf(num, &i);
return fw::floor(i);
}
struct intdec{
int integer;
double decimal;
intdec(){
integer = int();
decimal = double();
}
intdec & set(double num){
double i;
decimal = modf(num, &i);
integer = fw::floor(i);
return *this;
}
intdec & operator= (double num){ return set(num); }
intdec & operator() (double num){ return set(num); }
intdec(double num){ set(num); }
};
class real{
double mydouble;
public:
real(){ mydouble = double(); }
template<typename X>
real & subs(X num){
mydouble = (double)num;
return *this;
}
template<typename X>
real & operator= (X num){ return subs(num); }
template<typename X>
real(X num){ subs(num); }
double num() const { return mydouble; }
template<typename X>
operator X () const { return (X)mydouble; }
bool equal(real num) const {
fw::intdec my(mydouble);
fw::intdec req(num.num() );
if(my.integer != req.integer) return false;
if(my.decimal != req.decimal) return false;
return true;
}
bool operator== (real num) const { return equal(num); }
bool inequal(real num) const { return !equal(num); }
bool operator!= (real num) const { return inequal(num); }
bool big(real num) const {
fw::intdec my(mydouble);
fw::intdec req(num.num() );
if(my.integer > req.integer) return true;
if(my.integer == req.integer) if(my.decimal > req.decimal) return true;
return false;
}
bool operator> (real num) const { return big(num); }
bool smalequal(real num) const { return !big(num); }
bool operator<= (real num) const { return smalequal(num); }
bool smal(real num) const {
fw::intdec my(mydouble);
fw::intdec req(num.num() );
if(my.integer < req.integer) return true;
if(my.integer == req.integer) if(my.decimal < req.decimal) return true;
return false;
}
bool operator< (real num) const { return smal(num); }
bool bigequal(real num) const { return !smal(num); }
bool operator>= (real num) const { return bigequal(num); }
real & operator+= (real num){
mydouble += num.num();
return *this;
}
real & operator-= (real num){
mydouble -= num.num();
return *this;
}
real & operator*= (real num){
mydouble *= num.num();
return *this;
}
real & operator/= (real num){
mydouble /= num.num();
return *this;
}
real operator+ (real num) const {
real r = mydouble + num.num();
return r;
}
real operator- (real num) const {
real r = mydouble - num.num();
return r;
}
real operator* (real num) const {
real r = mydouble * num.num();
return r;
}
real operator/ (real num) const {
real r = mydouble / num.num();
return r;
}
};
fw::real inline pow(fw::real target, int exponent){ return ::pow(target.num(), exponent); }
int inline pow(int target, int exponent){ return (int)::pow( (double)target, exponent); }
fw::real inline sqrt(fw::real num){ return ::sqrt(num.num() ); }
struct coor{
fw::real x;
fw::real y;
coor(){}
coor & set(fw::real x, fw::real y){
this->x = x;
this->y = y;
return *this;
}
coor(fw::real x, fw::real y){ set(x,y); }
coor & operator() (fw::real x, fw::real y){ return set(x,y); }
coor & operator+= (const coor & another){
x += another.x;
y += another.y;
return *this;
}
bool operator== (const coor & another){
if(x != another.x) return false;
if(y != another.y) return false;
return true;
}
};
struct line{
fw::real a;
fw::real b;
bool useful;
line(){ useful = false; }
line & set(const coor & beg, const coor & end){
if(beg.x == end.x){
useful = false;
a = 0.0;
b = beg.x;
}
else{
useful = true;
a = (beg.y-end.y) / (beg.x-end.x);
b = beg.y - a*beg.x;
}
return *this;
}
line(const coor & beg, const coor & end){ set(beg, end); }
line & operator() (const coor & beg, const coor & end){ return set(beg, end); }
};
struct housen{
fw::line myline;
housen(){}
housen & set(const fw::line & l, const fw::coor & dot){
myline.useful = true;
if(l.useful){
if(l.a==0){
myline.useful = false;
myline.a = 0;
myline.b = dot.x;
}
else{
myline.a = -1.0/(double)l.a;
myline.b = dot.y - myline.a*dot.x;
}
}
else{
myline.a = 0;
myline.b = dot.y;
}
return *this;
}
housen(const fw::line & l, const fw::coor & dot){ set(l, dot); }
housen & operator() (const fw::line & l, const fw::coor & dot){ set(l, dot); }
operator fw::line () const { return myline; }
};
struct cross : public coor{
bool useful;
bool intersect;
bool parallel;
cross(){ useful = false; }
bool compute(const fw::line & one,const fw::line & another){
if(one.a==another.a && one.useful==another.useful){
useful = false;
intersect = one.b==another.b;
return parallel = intersect;
}
useful = true;
intersect = true;
parallel = false;
if(one.useful==false){
x = one.b;
y = another.a*x + another.b;
return true;
}
if(another.useful==false){
x = another.b;
y = one.a*x + one.b;
return true;
}
if(one.a == 0){
y = one.b;
x = (y-another.b) / another.a;
return true;
}
if(another.a == 0){
y = another.b;
x = (y-one.b) / one.a;
return true;
}
x = (another.b-one.b) / (one.a-another.a);
y = one.a*x + one.b;
return true;
}
cross(const fw::line & one,const fw::line & another){ compute(one, another); }
bool operator() (const fw::line & one,const fw::line & another){ return compute(one, another); }
};
fw::real inline distance(const fw::coor & one, const fw::coor & another){
fw::real width = one.x-another.x;
fw::real height = one.y-another.y;
return sqrt(pow(width,2)+pow(height,2) );
}
struct quad{
fw::coor tops[4];
quad(){}
quad & set(coor a, coor b, coor c, coor d){
tops[0] = a;
tops[1] = b;
tops[2] = c;
tops[3] = d;
return *this;
}
quad(coor a, coor b, coor c, coor d){ set(a,b,c,d); }
quad & set(const coor & lt, const coor & rb){
tops[0] = lt;
tops[1] = coor(lt.x,rb.y);
tops[2] = rb;
tops[3] = coor(rb.x,lt.y);
return *this;
}
quad(const coor & lt, const coor & rb){ set(lt, rb); }
};
struct triangle{
coor tops[3];
triangle(){}
triangle & set(const coor & f, const coor & s, const coor & t){
tops[0] = f;
tops[1] = s;
tops[2] = t;
return *this;
}
triangle(const coor & f, const coor & s, const coor & t){ set(f,s,t); }
};
struct circle{
coor o;
int r;
circle(){}
circle & set(coor o, int r){
this->o = o;
this->r = r;
return *this;
}
circle(coor o, int r){ set(o,r); }
circle & set(int x,int y, int r){
this->o = coor(x,y);
this->r = r;
return *this;
}
circle(int x,int y, int r){ set(x,y, r); }
};
class figure{
fw::vector<coor> tops;
int r;
bool cflag;
int myx1, myy1;
int myx2, myy2;
void myset(const fw::vector<coor> & tops){
this->tops = tops;
myx1 = (int)tops[0].x;
myy1 = (int)tops[0].y;
myx2 = myx1;
myy2 = myy1;
for(fw::uint i=1;i<tops.size();i++){
int x = (int)tops[i].x;
if(x < myx1) myx1 = x;
if(x > myx2) myx2 = x;
int y = (int)tops[i].y;
if(y < myy1) myy1 = y;
if(y > myy2) myy2 = y;
}
}
void mysetc(const circle & c){
cflag = true;
tops.setsize(1);
tops.last() = c.o;
r = c.r;
myx1 = c.o.x - c.r;
myy1 = c.o.y - c.r;
myx2 = c.o.x + c.r;
myy2 = c.o.y + c.r;
}
public:
figure & init(){
tops.setsize(0);
r = 0;
cflag = false;
myx1 = 0;
myy1 = 0;
myx2 = 0;
myy2 = 0;
return *this;
}
const fw::vector<coor> & topsdata() const { return tops; }
int rdata() const { return r; }
bool cflagdata() const { return cflag; }
figure & operator= (const figure & f){
tops = f.topsdata();
r = f.rdata();
cflag = f.cflagdata();
myx1 = f.x1();
myy1 = f.y1();
myx2 = f.x2();
myy2 = f.y2();
return *this;
}
figure & operator= (const quad & q){
myset(fw::vector<coor>(&(q.tops[0]), 4) );
return *this;
}
figure & operator= (const triangle & t){
myset(fw::vector<coor>(&(t.tops[0]), 3) );
return *this;
}
figure & operator= (const circle & c){
mysetc(c);
return *this;
}
figure(){ init(); }
figure(const figure & f){ *this = f; }
figure(const quad & q){ *this = q; }
figure(const triangle & t){ *this = t; }
figure(const circle & c){ *this = c; }
figure & operator+= (const coor & top){
tops += top;
int x = (int)top.x;
if(x < myx1) myx1 = x;
if(x > myx2) myx2 = x;
int y = (int)top.y;
if(y < myy1) myy1 = y;
if(y > myy2) myy2 = y;
return *this;
}
figure & operator<< (const coor & top){ return *this += top; }
int x1() const { return myx1; }
int y1() const { return myy1; }
int x2() const { return myx2; }
int y2() const { return myy2; }
const coor & operator[] (fw::uint index) const {
return tops[index];
}
fw::uint size() const { return tops.size(); }
void draw(const coor & base, int color, int thick = 1) const {
for(uint i=0;i<size();++i){
uint next = (i+1) % size();
DrawLine(base.x+tops[i].x,base.y+tops[i].y, base.x+tops[next].x,base.y+tops[next].y, color, thick);
}
}
};
class Mouse{
int myx, myy;
uint crossing(const fw::coor dist, const line & segment, const coor & beg,const coor & end) const {
fw::line ray(fw::coor(myx,myy), dist);
fw::cross c(ray, segment);
if(c.intersect==false) return 0; //交点がなければ0を返す
if(c.parallel){
//半直線と図形の一辺(線分)が平行のとき。それが半直線上にあるなら問答無用で半直線を変更する。そうでなければ交点なし
fw::real basevecx = dist.x-myx;
fw::real vecx1 = beg.x-myx;
fw::real vecx2 = end.x-myx;
if(basevecx*vecx1 < 0 && basevecx*vecx2 < 0) return 2;
fw::real basevecy = dist.y-myy;
fw::real vecy1 = beg.y-myy;
fw::real vecy2 = end.y-myy;
if(basevecy*vecy1 < 0 && basevecy*vecy2 < 0) return 2;
return 0;
}
fw::real basevecx(dist.x-myx);
fw::real vecx(c.x-myx);
if(basevecx*vecx < 0) return 0; //交点のx成分が無限遠の方向になければ交点なし
fw::real basevecy(dist.y-myy);
fw::real vecy(c.y-myy);
if(basevecy*vecy < 0) return 0; //交点のy成分が無限遠の方向になければ交点なし
fw::real most = fw::distance(beg, end);
fw::real sub1 = fw::distance(beg, c);
fw::real sub2 = fw::distance(end, c);
if(sub1>most || sub2>most) return 0; //直線として考えたときの交点が線分上になければ交点なし
if(c==beg || c==end) return 2; //半直線が頂点を通るようなら半直線を変更する
return 1;
}
fw::coor Get2DJoypadAngle(int joygle) const {
int jg = joygle % 8000;
if(jg < 0) jg = 8000 - abs(jg);
if(jg <= 1000) return fw::coor(jg, 1000);
if(jg <= 3000) return fw::coor(1000, 1000 - (jg-1000) );
if(jg <= 5000) return fw::coor(1000 - (jg-3000), -1000);
if(jg <= 7000) return fw::coor(-1000, -1000 + (jg-5000) );
return fw::coor(-1000 + (jg-7000), 1000);
}
bool inside(const fw::vector<coor> & v) const {
fw::coor dist(0+myx,1000+myy);
int joygle = 8000 / (v.size()+1);
int gap = 0;
uint num = 0;
for(uint i = 0;i < v.size();){
uint next = (i+1)%v.size();
line segment(v[i], v[next]);
uint result = crossing(dist, segment, v[i],v[next]);
if(result == 2){
gap += joygle;
dist = Get2DJoypadAngle(gap);
dist.x += myx;
dist.y += myy;
i = 0;
num = 0;
continue;
}
if(result == 1) ++num;
++i;
}
return num%2 == 1;
}
bool insidec(const coor & base, int r) const {
fw::real length = fw::distance(base, coor(myx,myy) );
return length <= r;
}
public:
Mouse(){
GetMousePoint(&myx, &myy);
}
void refresh(){
GetMousePoint(&myx, &myy);
}
bool in(const coor & base, const fw::figure & f) const {
if(f.cflagdata() ) return insidec(base, f.rdata() );
fw::vector<coor> v;
v.requre(f.size() );
for(uint i=0;i<f.size();++i){
coor c;
c.x = base.x + f[i].x;
c.y = base.y + f[i].y;
v += c;
}
return inside(v);
}
int x() const { return myx; }
int y() const { return myy; }
};
}
int WINAPI WinMain(HINSTANCE hI, HINSTANCE hP, LPSTR lpC, int nC){
ChangeWindowMode(true);
SetOutApplicationLogValidFlag(false);
SetWindowText("InsideProject");
SetMultiThreadFlag(false);
if(DxLib_Init() == -1) return(-1);
SetAlwaysRunFlag(false);
SetDrawScreen(DX_SCREEN_BACK);
SetDragFileValidFlag(false);
while(ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0){
ClsDrawScreen();
ScreenFlip();
}
DxLib_End();
return(0);
}