Zderzenia Kul

0

Cześć! "Piszę" bilarda w C. Szukałem w internecie modelu zderzenia idealnie sprężystego kul, niestety na 2 kody, obydwa były błędne. Napisałem, więc swój własny, jednak czasem kule przy zderzeniu blokują się w sobie, a czasem odbicie wygląda jak najbardziej poprawnie. Ma ktoś pomysł co może być źle?

#include <stdio.h>
#include <math.h>
#include "winbgi2.h"
#include <time.h>
#include <stdlib.h>
#define N 10
void przesun(double *x, double *y, double *vx, double *vy, double *r)
{
	for (int i = 0; i < N; ++i) {
		if (x[i] + r[i] > 1128.0 || x[i] - r[i] < 30.0) {
			vx[i] = -vx[i];
	
		}
		else if (y[i] + r[i] > 579.0 || y[i] - r[i] < 30.0) {
			vy[i] = -vy[i];
		
		}
		x[i] += vx[i];
		y[i] += vy[i];
	}
}

void searchAndCollide(double* x, double* y, double *vx, double *vy, double *r) {
	int i;
	int j;
	double L;
	double pi = acos(-1);
	double vxn[N], vyn[N];
	for (i = 1; i < N; i++)
	{

		for (j = 0; j < i; j++)
		{
			if (sqrt(pow(x[i] - x[j], 2.0) + pow(y[i] - y[j], 2.0)) - (r[i] + r[j]) < 0.0) {
				double collisionPoint[2] = { (x[i] * r[j] + x[j] * r[i]) / (r[i] + r[j]),(y[i] * r[j] + y[j] * r[i]) / (r[i] + r[j]) };
				double tetai= atan((x[i] - x[j]) / (y[i] - y[j]));
				double tetaj = atan((y[i] - y[j]) / (x[i] - x[j]));
				double fii = atan(vx[i] / vy[i]);
				double fij = atan(vy[j] / vx[j]);
				double alfai = tetai - fii;
				double alfaj = tetaj - fij;
				double vwi = sqrt(pow(vx[i], 2.0) + pow(vy[i], 2.0));
				double vwj = sqrt(pow(vx[j], 2.0) + pow(vy[j], 2.0));
				vxn[i] = vwi*cos(alfai);
				vxn[j] = vwj*cos(alfaj);
				vyn[i] = vwi*sin(alfai);
				vyn[j] = vwj*sin(alfaj);
				double V1[2] = { (vxn[i] * (r[i] - r[j]) + (2 * r[j] * vxn[j])) / (r[i] + r[j]),vyn[i]};
				double V2[2] = { (vxn[j] * (r[j] - r[i]) + (2 * r[i] * vxn[i])) / (r[i] + r[j]),vyn[j]};
				double vwni = sqrt(pow(V1[0], 2) + pow(V1[1], 2));
				double vwnj = sqrt(pow(V2[0], 2) + pow(V2[1], 2));
				double gammai = acos(V1[0] / vwni);
				double gammaj = acos(V2[0] / vwnj);
				double kati = tetai-gammai;
				double katj = tetaj-gammaj;
				vx[i] =vwni*sin(kati);
				vy[i] =vwni*cos(kati);
				vx[j] = vwnj*cos(katj);
				vy[j] = vwnj*sin(katj);
			}
		
		}
	}
}
void main()
{
	double PI = acos(-1);
	graphics(1600, 1600);
	double r[N];
	for (int i = 0; i < N;i++) {
		r[i] = 20.0;
	}
	r[0]=30;
	double x[N];
	double y[N];
	
	x[0] = 868.5;
	y[0] = 304.5;
	x[1] = 290.0;
	y[1] = 304.5;
	x[2] = x[1] - 50.0;
	y[2] = y[1] + 50.0;
	x[3] = x[1] + 50.0;
	y[3] = y[1] + 50.0;
	x[4] = x[3] - 50.0;
	y[4] = y[3] + 50.0;
	x[5] = x[2] - 50.0;
	y[5] = y[1];
	x[6] = x[3] + 50.0;
	y[6] = y[1];
	x[7] = x[5] + 50.0;
	y[7] = y[5] - 50.0;
	x[8] = x[3];
	y[8] = y[7];
	x[9] = x[1];
	y[9] = x[8] - 100.0;



	double vx[N];
	double vy[N];
	double v[N];
	

	vx[0] = -5;
		vy[0] = 1;
		v[0] = sqrt(pow(vx[0], 2.0) + pow(vy[0], 2.0));

		for (int i = 1; i < N; i++)
		{
			vx[i] = 1;
			vy[i] =1;
		}
	
	
	while (animate(100)) {
		clear();
		line(30, 579, 1128, 579);
		line(30, 30, 1128, 30);
		line(30, 30, 30,579);
		line(1128, 30, 1128,579);

		line(0, 609,1158,609);
		line(0, 0, 1158, 0);
		line(0, 0, 0, 609);
		line(1158, 0, 1158, 609);

		pieslice(579, 30,360,180,22);
		pieslice(579, 579, 180, 360, 22);
		pieslice(30,30,0,270, 22);
		pieslice(30, 579, 90, 360, 22);
		pieslice(1128, 579, 180, 90,22);
		pieslice(1128, 30, 270, 180, 22);

		for (int i = 0; i < N; i++)
			circle(x[i], y[i], r[i]);
		searchAndCollide(x, y, vx, vy, r);
		przesun(x, y, vx, vy, r);
		

	}
	wait();

Napisane w Visual Studio, język C

0

Pewnie chodzi o to że gdy środki kul znajdą się bliżej niż suma promieni kul to nastąpi zmiana wektorów prędkości, jednak przy kolejnym cyklu sprawdzania zderzenia kule nie zdążą wyjść spoza zakresu penetracji (czyli odległość między środkami kul będzie wciąż mniejsza niż suma promieni) i wektor prędkości znowu zostanie odwrócony i tak będzie w kółko co obrót pętli głównej, w konsekwencji będzie to wyglądać tak jakby kule się zlepiły.
Musisz zapewnić żeby kule nie kolidowały ze sobą przy kolejnym sprawdzaniu zderzenia, np zrobić tak że gdy kule się zderzają lekko nagiąć prawa fizyki i zmienić ich położenie na takie, które zapewni że już nie będą ze sobą kolidować przy następnym sprawdzaniu zderzenia. Najlepiej zapewnić by odległość między środkami była co najmniej równa sumie promieni kul.

1 użytkowników online, w tym zalogowanych: 0, gości: 1