diff options
Diffstat (limited to 'testsat.cpp')
| -rw-r--r-- | testsat.cpp | 155 | 
1 files changed, 155 insertions, 0 deletions
diff --git a/testsat.cpp b/testsat.cpp new file mode 100644 index 0000000..45f3891 --- /dev/null +++ b/testsat.cpp @@ -0,0 +1,155 @@ +#include <SDL2/SDL.h> + +#include <assert.h> +#include <stdlib.h> + +#include "maths.cpp" + +struct Shape { +	v2f* points; +	int count; + +	Shape(std::initializer_list<v2f> in) { +		int i; +		points = (v2f*)malloc(in.size() * sizeof *points); +		count = in.size(); +		for (i = 0; i < count; i++) +			points[i] = *(in.begin() + i); +	} + +	Shape(const Shape& other) { +		int s = other.count * sizeof *points; +		count = other.count; +		points = (v2f*)malloc(s); +		memcpy(points, other.points, s); +	} + +	~Shape() { +		free(points); +	} + +	void render(SDL_Renderer* ren) { +		int i, c = count; +		for (i = 0; i < c; i++) { +			v2f a = points[i]; +			v2f b = points[(i + 1) % c]; +			SDL_RenderDrawLine( +				ren, +				(int)a.x, +				(int)a.y, +				(int)b.x, +				(int)b.y +			); +		} +	} + +	std::pair<v2f*, int> normals() const { +		int c = (count >> 1) + 1, i; +		v2f* normals = (v2f*)malloc(c * sizeof *normals); +		for (i = 0; i < count; i++) { +			v2f a = points[i]; +			v2f b = points[(i + 1) % count]; +			v2f e = a - b; +			v2f n = v2f::normalised(v2f(e.y, -e.x)); +			normals[i] = n; +		} +		return { normals, i }; +	} +}; + +bool intersect(Shape& a, Shape& b) { +	bool r = true; +	int i; +	auto[fn, fnc] = a.normals(); +	auto[sn, snc] = b.normals(); +	auto project = [](const Shape& shape, v2f axis) { +		int i; +		float mini =  INFINITY; +		float maxi = -INFINITY; +		for (i = 0; i < shape.count; i++) { +			v2f p = shape.points[i]; +			float d = v2f::dot(p, axis); +			if (d < mini) mini = d; +			if (d > maxi) maxi = d; +		} +		return std::pair<float, float>{ mini, maxi }; +	}; +	for (i = 0; i < fnc; i++) { +		v2f axis = fn[i]; +		auto [fp1, fp2] = project(a, axis); +		auto [sp1, sp2] = project(b, axis); +		if (fp2 > sp1 && fp1 > sp2) { +			r = false; +			goto end; +		} +	} +	for (i = 0; i < snc; i++) { +		v2f axis = sn[i]; +		auto [fp1, fp2] = project(a, axis); +		auto [sp1, sp2] = project(b, axis); +		if (fp2 > sp1 && fp1 > sp2) { +			r = false; +			goto end; +		} +	} +end: +	free(fn); +	free(sn); +	return r; +} + +int main(int argc, const char** argv) { +	int r = 1; +	SDL_Window* window; +	SDL_Renderer* ren; +	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK); +	SDL_CreateWindowAndRenderer( +		800, +		800, +		0, +		&window, +		&ren +	); +	Shape a({ +		v2f(300.0f, 300.0f), +		v2f(400.0f, 400.0f), +		v2f(250.0f, 500.0f), +	}); +	Shape tri({ +		v2f(0.0f, 0.0f), +		v2f(50.0f, 200.0f), +		v2f(200.0f, 100.0f), +	}); +	while (r) { +		int i; +		SDL_Event e; +		while (SDL_PollEvent(&e)) { +			switch (e.type) { +				case SDL_QUIT: +					r = 0; +					break; +			} +		} +		int mx, my; +		SDL_GetMouseState(&mx, &my); +		Shape b(tri); +		for (i = 0; i < b.count; i++) { +			v2f& p = b.points[i]; +			p.x += mx; +			p.y += my; +		} +		SDL_SetRenderDrawColor(ren, 0x00, 0x00, 0x00, 0x00); +		SDL_RenderClear(ren); +		SDL_SetRenderDrawColor(ren, 0xff, 0x00, 0xff, 0xff); +		a.render(ren); +		if (intersect(a, b)) { +			SDL_SetRenderDrawColor(ren, 0xff, 0x00, 0x00, 0xff); +		} +		b.render(ren); +		SDL_RenderPresent(ren); +	} +	SDL_DestroyRenderer(ren); +	SDL_DestroyWindow(window); +	SDL_Quit(); +	return 0; +}  |