powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Программирование [игнор отключен] [закрыт для гостей] / [c++, opengl] моделирование ткани
10 сообщений из 10, страница 1 из 1
[c++, opengl] моделирование ткани
    #35683258
Дональдак
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день!

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

Алгоритм такой:
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
[c++, opengl] моделирование ткани
    #35683262
Дональдак
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
[c++, opengl] моделирование ткани
    #35683274
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Непонятно, а что должно было получится в правильном варианте?
...
Рейтинг: 0 / 0
[c++, opengl] моделирование ткани
    #35683283
Дональдак
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ткань должна опуститься до вертикального положения.
...
Рейтинг: 0 / 0
[c++, opengl] моделирование ткани
    #35683309
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А почему конструктор спрятал?
...
Рейтинг: 0 / 0
[c++, opengl] моделирование ткани
    #35683327
Дональдак
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Просто уменьшал количество строк кода.
Вот он:
Код: 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
[c++, opengl] моделирование ткани
    #35683340
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Меня удивляет что точки. за которые ты укрепил штору тоже находятся отнюдь не горизонтально. Может быть ты просто неверно задал настройки камеры и получил sqew+rotate. И почему ткань должна падать? Все точки имеют нулевую массу, следовательно гравитация на них не должна дествовать.
...
Рейтинг: 0 / 0
[c++, opengl] моделирование ткани
    #35683368
Дональдак
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Насчет камеры: да, возможно,но я перепробывал массу вариантов и оптимального так и не нашел (камера всегда была моим слабым местом), если вы подскажете мне лучший, я буду очень благодарен.

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

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


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