Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Программирование [игнор отключен] [закрыт для гостей] / [c++, opengl] моделирование ткани / 10 сообщений из 10, страница 1 из 1
29.11.2008, 09:51:41
    #35683258
Дональдак
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[c++, opengl] моделирование ткани
Добрый день!

Столкнулся с такой ситуацией: необходимо смоделировать падение ткани, закрепленной с одной стороны в нескольких точках (метод частиц + обратный метод Эйлера). Простым языком - штора.

Алгоритм такой:
1. Разбиваем ткань на точки, считаем их массы, закрепляем некоторые точки на одной из сторон.
2. Считаем силы, действующие на точки (внутренние + внешние)
3. Зная силу и массу, вычисляем ускорение, скорость и, наконец, перемещение.

Вроде не сложно, но возникла проблема: ткань падает отлично до определенного момента (где-то до половины пути), а потом замирает, только чуть колышется. Источник проблемы я не могу найти уже несколько дней.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
...

const double MaxSizeWindow =  120 ;
const double HalfMaxSizeWindow =  0 . 5  * MaxSizeWindow;
const int AmountFixedPointsMin =  5 ;
const double g =  9 . 80665 ;
const double dt =  0 . 01 ;

struct PointPositions
{
	bool fixed;

	double XPrimary, YPrimary, ZPrimary,
		XCurrent, YCurrent, ZCurrent;

	double Mass;

	double ForceX, ForceY, ForceZ;

	double AccelerationX, AccelerationY, AccelerationZ,
		SpeedX, SpeedY, SpeedZ;
};

class ModelingMaterial
{
	int LengthMaterial,
		WidthMaterial,
		PointsX,
		PointsY;
	
	double Ks, Kb, Kt;

	double C;

	double Density;

	PointPositions *tmp;

public:
	ModelingMaterial(const int, const int, const int, const int, 
					const double, const double, const double, const double, const double);
	~ModelingMaterial(void);
	void StartDrawing(void);
	void SetFixedPoints(void);
	void CalculateInsideForce(const int, const int, const int, const int, 
							double &, double &, double &);
	void CalculateAllInsideForces(void);
	void CalculatePointMass(void);
	void CalculateNewPositions(void);
	void StartSimulation(void);
	void CheckDistances(void);
	void ReDrawPicture(void);
};

...

void ModelingMaterial::CheckDistances()
{
	for(int x = PointsY -  1 ; x >=  0 ; x--)
		for(int y = PointsX -  1 ; y >=  0 ; y--)
			for(int k = x -  1 ; k <= x +  1 ; k++)
			{
				if(k <  0  || k > PointsY -  1 ) continue;

				for(int m = y -  1 ; m <= y +  1 ; m++)
				{
					if(m <  0  || m > PointsX -  1 ) continue;
					
					if(k == x && m == y) continue;

					if((k == x +  1  || k == x -  1 ) && (m == y +  1  || m == y -  1 )) continue;

					while(tmp[x * PointsX + y].ZCurrent < tmp[k * PointsX + m].ZCurrent -  0 . 02 )
					{	
							tmp[k * PointsX + m].ZCurrent -=  0 . 001 ;
					}
				}
			}
}

void ModelingMaterial::CalculateNewPositions()
{
	double Fx, Fy, Fz, Ax, Ay, Az, Vx, Vy, Vz;

	for(int i =  0 ; i < PointsY; i++)
		for(int j =  0 ; j < PointsX; j++)
		{
			if(tmp[i * PointsX + j].fixed == true) continue;

			Fx = tmp[i * PointsX + j].ForceX + C * tmp[i * PointsX + j].SpeedX;

			Fy = tmp[i * PointsX + j].ForceY + C * tmp[i * PointsX + j].SpeedY;

			Fz = tmp[i * PointsX + j].ForceZ + C * tmp[i * PointsX + j].SpeedZ + 
				tmp[i * PointsX + j].Mass * g;

			Ax = Fx / tmp[i * PointsX + j].Mass;

			Ay = Fy / tmp[i * PointsX + j].Mass;

			Az = Fz / tmp[i * PointsX + j].Mass;

			Vx = tmp[i * PointsX + j].SpeedX + dt /  2  
				* (tmp[i * PointsX + j].AccelerationX + Ax);

			Vy = tmp[i * PointsX + j].SpeedY + dt /  2  
				* (tmp[i * PointsX + j].AccelerationY + Ay);

			Vz = tmp[i * PointsX + j].SpeedZ + dt /  2  
				* (tmp[i * PointsX + j].AccelerationZ + Az);

			tmp[i * PointsX + j].XCurrent += dt /  2  * (tmp[i * PointsX + j].SpeedX + Vx);
			tmp[i * PointsX + j].YCurrent += dt /  2  * (tmp[i * PointsX + j].SpeedY + Vy);
			tmp[i * PointsX + j].ZCurrent += dt /  2  * (tmp[i * PointsX + j].SpeedZ + Vz);


			tmp[i * PointsX + j].AccelerationX = Ax;
			tmp[i * PointsX + j].AccelerationY = Ay;
			tmp[i * PointsX + j].AccelerationZ = Az;

			tmp[i * PointsX + j].SpeedX = Vx;
			tmp[i * PointsX + j].SpeedY = Vy;
			tmp[i * PointsX + j].SpeedZ = Vz;
		}

		CalculateAllInsideForces();
}

void ModelingMaterial::StartSimulation()
{
	for(double t = dt; t <  1 . 1 ; t += dt)
	{
		CalculateNewPositions();
		CheckDistances();
		ReDrawPicture();
	}
}

void reshape(int w, int h)
{
	glViewport( 0 ,  0 , w, h);
  
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	if (w >= h)
	{
		double f = static_cast<double>(h) / static_cast<double>(w);
		glOrtho(-HalfMaxSizeWindow, HalfMaxSizeWindow, 
				-HalfMaxSizeWindow * f, HalfMaxSizeWindow * f, - 500 ,  500 );
	}
	else
	{
		double f = static_cast<double>(w) / static_cast<double>(h);
		glOrtho(-HalfMaxSizeWindow * f, HalfMaxSizeWindow * f, 
				-HalfMaxSizeWindow, HalfMaxSizeWindow, - 500 ,  500 );
	}

	glMatrixMode(GL_MODELVIEW);
}

void display(void)
{
	ModelingMaterial ob( 80 ,  50 ,  40 ,  25 ,  50 ,  50 ,  50 ,  0 . 150 , - 0 . 5 ); //density of cotton kg/(m*m)
	ob.StartDrawing();
	ob.SetFixedPoints();
	ob.CalculatePointMass();
	ob.StartSimulation();
}

Вот до такого положения процесс идет и останавливается!
...
Рейтинг: 0 / 0
29.11.2008, 09:57:58
    #35683262
Дональдак
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[c++, opengl] моделирование ткани
...
Рейтинг: 0 / 0
29.11.2008, 10:32:32
    #35683274
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[c++, opengl] моделирование ткани
Непонятно, а что должно было получится в правильном варианте?
...
Рейтинг: 0 / 0
29.11.2008, 10:54:49
    #35683283
Дональдак
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[c++, opengl] моделирование ткани
Ткань должна опуститься до вертикального положения.
...
Рейтинг: 0 / 0
29.11.2008, 11:41:24
    #35683309
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[c++, opengl] моделирование ткани
А почему конструктор спрятал?
...
Рейтинг: 0 / 0
29.11.2008, 12:01:03
    #35683327
Дональдак
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[c++, opengl] моделирование ткани
Просто уменьшал количество строк кода.
Вот он:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
ModelingMaterial::ModelingMaterial(const int LM, const int WM, const int PX, const int PY, 
									const double ks, const double kb, const double kt, 
									const double D, const double c)
{
	LengthMaterial = LM;
	WidthMaterial = WM;
	PointsX = PX;
	PointsY = PY;
	Ks = ks;
	Kb = kb;
	Kt = kt;
	Density = D;
	C = c;


	tmp = new PointPositions[PointsX * PointsY];

	if(!tmp) exit(- 1 );

	for(int i =  0 ; i < PointsY; i++)
		for(int j =  0 ; j < PointsX; j++)
	{
			tmp[i * PointsX + j].XPrimary =  0 ;
			tmp[i * PointsX + j].YPrimary =  0 ;
			tmp[i * PointsX + j].ZPrimary =  0 ;

			tmp[i * PointsX + j].XCurrent =  0 ;
			tmp[i * PointsX + j].YCurrent =  0 ;
			tmp[i * PointsX + j].ZCurrent =  0 ;

			tmp[i * PointsX + j].fixed = false;

			tmp[i * PointsX + j].Mass =  0 ;

			tmp[i * PointsX + j].ForceX =  0 ; 
			tmp[i * PointsX + j].ForceY =  0 ; 
			tmp[i * PointsX + j].ForceZ =  0 ; 

			tmp[i * PointsX + j].AccelerationX =  0 ; 
			tmp[i * PointsX + j].AccelerationY =  0 ; 
			tmp[i * PointsX + j].AccelerationZ =  0 ;

			tmp[i * PointsX + j].SpeedX =  0 ; 
			tmp[i * PointsX + j].SpeedY =  0 ; 
			tmp[i * PointsX + j].SpeedZ =  0 ;
	}
}

...
Рейтинг: 0 / 0
29.11.2008, 12:44:36
    #35683340
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[c++, opengl] моделирование ткани
Меня удивляет что точки. за которые ты укрепил штору тоже находятся отнюдь не горизонтально. Может быть ты просто неверно задал настройки камеры и получил sqew+rotate. И почему ткань должна падать? Все точки имеют нулевую массу, следовательно гравитация на них не должна дествовать.
...
Рейтинг: 0 / 0
29.11.2008, 13:37:19
    #35683368
Дональдак
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[c++, opengl] моделирование ткани
Насчет камеры: да, возможно,но я перепробывал массу вариантов и оптимального так и не нашел (камера всегда была моим слабым местом), если вы подскажете мне лучший, я буду очень благодарен.

Насчет массы, выше - это лишь конструктор. Есть функция, которая назначает массу для каждой точки (исходя из плотности материала и линейных размеров, а также положения точки, в углу, на краю или же в середине). В результате на точки действует сила тяжести, а после первой итерации начинают действовать внутренние силы и сила затухания.
...
Рейтинг: 0 / 0
29.11.2008, 14:04:06
    #35683387
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[c++, opengl] моделирование ткани
Начать следует с правильной установки камеры. К сожалению я давно занимался с OpenGL и уже не вспомню как это делается. Но для простоты настройки тебе надо нарисовать объект-маркер. Например пирамида. Поставить её так чтобы она указывала направление вектора гравитации и горизонт. По ней надо правильно выставить камеру.

Ну а дальше разбиратсься с точками.
...
Рейтинг: 0 / 0
29.11.2008, 14:38:25
    #35683405
Дональдак
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
[c++, opengl] моделирование ткани
Спасибо за совет, я попробую.
...
Рейтинг: 0 / 0
Форумы / Программирование [игнор отключен] [закрыт для гостей] / [c++, opengl] моделирование ткани / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]