当たり判定の処理を久しぶりに書いた。当たり判定処理は昔ActionScriptで書いていた頃にも少し遊びで作った事があるけど、とりあえずその頃やった事ぐらいの内容は実装しよう。確か円と線と矩形(AABB)同士の当たり判定だったかな?


#include "stdafx.h"

#include <windows.h>
#include <algorithm>
#include <cmath>

#include <assert.h>

__forceinline bool IsPointInRectangle(int x, int y, int l, size_t w, int t, size_t h)
{
	const size_t dx = x - l;
	const size_t dy = y - t;
	return dx <= w && dy <= h;
}

__forceinline bool IsPointInCircle(int px, int py, int cx, int cy, size_t r)
{
	const int dx = cx - px;
	const int dy = cy - py;
	return size_t(dx * dx) + size_t(dy * dy) <= r*r;
}

__forceinline bool IsPointInEllipse(int x, int y, int l, size_t w, int t, size_t h)
{
#if 1
	const int dx = ((l-x)<<1) + w;
	const int dy = ((t-y)<<1) + h;
	const double ww = w * w;
	return (dx * dx) + (dy * dy) * (ww / (h*h)) <= ww;
#else

	const int dx = ((l-x)<<1) + w;
	const int dy = ((t-y)<<1) + h;

	// 精度を犠牲にして整数で処理
	static const size_t PRECISION_SHIFTS = 8;
	const int ww = (w * w) << PRECISION_SHIFTS;
	return ((dx * dx) << PRECISION_SHIFTS) + (dy * dy) * (ww / (h * h)) <= ww;
#endif
}


__forceinline bool IsPointInEllipse(float x, float y, float l, float w, float t, float h)
{
	const float dx = (l-x) * 0.5f + w;
	const float dy = (t-y) * 0.5f + h;
	return (dx * dx) / (w * w) + (dy * dy) / (h * h) <= 1.0f;
}


int _tmain(int argc, _TCHAR* argv[])
{
	const size_t WIDTH = 2048;
	const size_t HEIGHT = 2048;
	char* buff = new char[WIDTH*HEIGHT];
	std::fill(buff, buff+WIDTH*HEIGHT, 0);


	LARGE_INTEGER start;
	QueryPerformanceCounter(&start);

	RECT rec1 = {10,10, WIDTH+400,HEIGHT+100};
	RECT rec2 = {110,110, WIDTH-130,HEIGHT-140};

	char* line = buff;
	for (size_t y=0; y<HEIGHT; ++y) {
		for (size_t x=0; x<WIDTH; ++x) {
			POINT pt = {x,y};
			if (IsPointInEllipse(pt.x, pt.y, rec1.left, rec1.right-rec1.left, rec1.top, rec1.bottom-rec1.top)) {
				line[x] += 70;
			}
/*
			if (IsPointInCircle(pt.x, pt.y, 250,250,200)) {
				line[x] += 70;
			}
			if (IsPointInRectangle(pt.x, pt.y, rec2.left, rec2.right-rec2.left, rec2.top, rec2.bottom-rec2.top)) {
				line[x] += 70;
			}
*/
		}
		line += WIDTH;
	}
	
	LARGE_INTEGER end;
	QueryPerformanceCounter(&end);
	
	LONGLONG elapsed = end.QuadPart - start.QuadPart;

	printf("%x, %ld\n", buff, elapsed);
	return 0;
}