Уравнение второго порядка

Есть ф-ия 2 порядка(3д кривая) надо как то её отобразить С помощью каких методов можно сделать такое?
0      1253        30.11.2010        14

0 
30.11.2010 00:00:00
Может быть можно ее разбить на части? Т.е. сформировать систему уравнений так, чтобы отдельно каждую координату вычислить можно было.
0 
30.11.2010 00:00:00
Функцию в студию!!!
0 
30.11.2010 00:00:00
я немного наверно не так сформулировал. Поверхность второго порядка надо построить, то есть
Что касается ф-ии, то любую. Н-р по ссылке что я дал — гиперболойд обыкновенный можно взять за основу. Я просто думал есть уже спец ф-ия или какой то метод в opengl для прорисовки поверхностей 2 порядка.
0 
30.11.2010 00:00:00
Я такое же рисовал неделю назад :)
Я вначале построил, то что хочу видеть с помощью Маткада и потом, по готовым функциям строил в Джеле кривую. У меня вышла обычная функция типа Z = sin(X)*sin(Y) (мне нужны были синусоидальные волны).

По поводу метода или спец функции пока ни чего не слышал. Может кто из умных людей заглянет и подскажет :)
0 
30.11.2010 00:00:00
Т.е. поидее этого должно хватить для рисования графика и определения любой точки данной поверхности.
0 
30.11.2010 00:00:00
а как ты сделал? ТО есть ты Z=0 и получил кривую и потом менял z и получил поверхность? Можешь показать кусок кода?
0 
01.12.2010 00:00:00
Привет! Ниже привожу функцию, которой я рисую график функции Z = sin(X)*cos(Y):
private void SinSin()
{
// prec_? - точность отображения поверхности.
// Т.е. чем больше точность, тем более плавной
// будет поверхность;
int prec_x = 50, prec_y = 50, i = 0, j = 0;
// Квадрат который отсекает поверхность по X и Y;
int pole = 10;
// Координаты точек поверхности;
double[] X = new double[prec_x], Y = new double[prec_y];
double[,] Z = new double[prec_x, prec_y];
for (double x = 0; Math.Round(x, 4) < pole;
x += (double)pole / (double)prec_x)
{
j = 0;
X[i] = x;
for (double y = 0; Math.Round(y,4) < pole;
y += (double)pole / (double)prec_y)
{
Y[j] = y;
// Ф-ция поверхности, которую будем отображать;
Z[i, j] = Math.Sin(X[i]) * Math.Sin(Y[j]);
j++;
}
i++;
}
// DRAWING.
double r, g, b;
r = g = b = 1.0f;
for (i = 0; i < prec_x - 1; i++)
{
r = 1.0f;
for (j = 0; j < prec_y - 1; j++)
{
// Рисуем поверхность треугольниками;
Gl.glColor3d(r, g, b);
Gl.glBegin(Gl.GL_TRIANGLES);
// 1
Gl.glVertex3d(X[i], Z[i,j], Y[j]);
Gl.glVertex3d(X[i], Z[i, j + 1], Y[j + 1]);
Gl.glVertex3d(X[i + 1], Z[i + 1, j], Y[j]);
// 2
Gl.glVertex3d(X[i], Z[i, j + 1], Y[j + 1]);
Gl.glVertex3d(X[i + 1], Z[i + 1, j], Y[j]);
Gl.glVertex3d(X[i + 1], Z[i + 1, j + 1], Y[j + 1]);
// End
Gl.glEnd();
r -= 1.0 / prec_y;
}
g -= 1.0 / prec_x;
}
}
Там конечно для нормального отображения нужно поворот сцены по осям сделать:
Gl.glRotatef(30.0f, 1.0f, -1.0f, 0.0f);
Если что-то непонятно, то пиши сюда.
0 
01.12.2010 00:00:00
график функции Z = sin(X)*cos(Y):Прошу прощения в этой функции я рисую график ф-ции Z = sin(X)*sin(Y).
0 
01.12.2010 00:00:00
то есть получается сначало математика, потом ты значения в матрицы записываешь, а потом матрицы воспроизводишь на сцене… Благодарствую. Буду разбираться…
0 
01.12.2010 00:00:00
В OpenGL всегда вначале математика ;-)
Попробуй мой пример скопировать и запустить, поиграй с параметрами prec_x, prec_y и pole и ты увидишь, что к чему. Это не единственный вариант решения (надеюсь :) для построения графиков, но пока лучше я лично ни чего не придумал. Можно только цветовую раскраску, как вот вставить.

PS: не забываем плюсовать, если информация была полезной :)
0 
01.12.2010 00:00:00
Совсем забыл, можно использовать Джелевские массивы вершин, тогда отрисовка поверхности будет проходить быстрее:
// Разрешаем использование массивов вершин;
Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY);
// Инициализируем точки вершин из массива;
Gl.glVertexPointer(3, Gl.GL_FLOAT, 0, ARR_VERTEX);
// Отрисовуем фигуру по точкам из памяти. Массив index
// задает последовательность соединения точек в фигуру;
Gl.glDrawElements(Gl.GL_TRIANGLES, index.Length,
Gl.GL_UNSIGNED_INT, index);
// Запрещаем массивы вершин;
Gl.glDisableClientState(Gl.GL_VERTEX_ARRAY);
Предварительно точки должны быть занесены в массив ARR_VERTEX и последовательность их соединения в массив index
Т.е. при таком подходе мы не рисуем каждый треугольник отдельно (избегаем дублирование точек), как мы это сделали в функции SinSin():
for (i = 0; i < prec_x - 1; i++)
{
r = 1.0f;
for (j = 0; j < prec_y - 1; j++)
{
// Рисуем поверхность треугольниками;
Gl.glColor3d(r, g, b);
Gl.glBegin(Gl.GL_TRIANGLES);
// 1
Gl.glVertex3d(X[i], Z[i,j], Y[j]);
Gl.glVertex3d(X[i], Z[i, j + 1], Y[j + 1]);
Gl.glVertex3d(X[i + 1], Z[i + 1, j], Y[j]);
// 2
Gl.glVertex3d(X[i], Z[i, j + 1], Y[j + 1]);
Gl.glVertex3d(X[i + 1], Z[i + 1, j], Y[j]);
Gl.glVertex3d(X[i + 1], Z[i + 1, j + 1], Y[j + 1]);
// End
Gl.glEnd();
r -= 1.0 / prec_y;
}
g -= 1.0 / prec_x;
}
А сразу прорисовываем на экране всю поверхность одним вызовом Gl.glDrawElements

Просто при ответе на твой вопрос я привел не сложный пример, поэтому и не использовал GL_VERTEX_ARRAY
0 
02.12.2010 00:00:00
А если надо ф-ию нарисовать Z^2=X^2+Y^2?
Я сделал у меня 2 массива Z,Z1 это верхняя парабола и нижняя. Только у меня как видно из картинки
она какая то обрезанная пополам получилась. Як так?


private void timer1_Tick(object sender, EventArgs e)
{
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
tick++;
Gl.glLoadIdentity();
Gl.glColor3f(1.0f, 0, 0);

Gl.glPushMatrix();
Gl.glTranslated(Global_x, Global_y, Global_z);
Gl.glRotated(Global_Rotated, 1, 1, 0);

Double pa = Global_pa, pb = Global_pb, pt = tick;

// prec_? - точность отображения поверхности.
// Т.е. чем больше точность, тем более плавной
// будет поверхность;
int prec_x = 50, prec_y = 50, i = 0, j = 0;
// Квадрат который отсекает поверхность по X и Y;
int pole = 10;
// Координаты точек поверхности;
double[] X = new double[prec_x], Y = new double[prec_y];
double[,] Z = new double[prec_x, prec_y];
double[,] Z1 = new double[prec_x, prec_y];
for (double x = 0; Math.Round(x, 4) < pole;
x += (double)pole / (double)prec_x)
{
j = 0;
X[i] = x;
for (double y = 0; Math.Round(y, 4) < pole;
y += (double)pole / (double)prec_y)
{
Y[j] = y;
// Ф-ция поверхности, которую будем отображать;
//Z[i, j] = Math.Sin(X[i]) * Math.Sin(Y[j]);
//Z[i, j] = Math.Sqrt((pa * pa * Math.Sin(pt) * Math.Sin(pt) * X[i] + pb * pb * Y[j] * Y[j]) / (pa * pa * pb * pb * Math.Sin(pt) * Math.Sin(pt))) - 1;
Z[i, j] =+Math.Sqrt(pa* X[i] * X[i] + pb*Y[j] * Y[j]);
Z1[i, j] = -Math.Sqrt(pa * X[i] * X[i] + pb * Y[j] * Y[j]);
j++;
}
i++;
}
// DRAWING.
double r, g, b;
r = g = b = 1.0f;
for (i = 0; i < prec_x - 1; i++)
{
r = 1.0f;
for (j = 0; j < prec_y - 1; j++)
{
// Рисуем поверхность треугольниками;
Gl.glColor3d(r, g, b);
Gl.glBegin(Gl.GL_TRIANGLES);
// 1
Gl.glVertex3d(X[i], Z[i, j], Y[j]);
Gl.glVertex3d(X[i], Z[i, j + 1], Y[j + 1]);
Gl.glVertex3d(X[i + 1], Z[i + 1, j], Y[j]);
// 2
Gl.glVertex3d(X[i], Z[i, j + 1], Y[j + 1]);
Gl.glVertex3d(X[i + 1], Z[i + 1, j], Y[j]);
Gl.glVertex3d(X[i + 1], Z[i + 1, j + 1], Y[j + 1]);
// End
// 1
Gl.glVertex3d(X[i], Z1[i, j], Y[j]);
Gl.glVertex3d(X[i], Z1[i, j + 1], Y[j + 1]);
Gl.glVertex3d(X[i + 1], Z1[i + 1, j], Y[j]);
// 2
Gl.glVertex3d(X[i], Z1[i, j + 1], Y[j + 1]);
Gl.glVertex3d(X[i + 1], Z1[i + 1, j], Y[j]);
Gl.glVertex3d(X[i + 1], Z1[i + 1, j + 1], Y[j + 1]);
// End
Gl.glEnd();
r -= 1.0 / prec_y;
}
g -= 1.0 / prec_x;
}
Gl.glPopMatrix();
Gl.glFlush();
AnT.Invalidate();
}
0 
03.12.2010 00:00:00
Смотрю обсуждение развилось: перенес в вопросы OpenGL + C#.
0 
04.12.2010 00:00:00
Здравствуйте!
Я не совсем понял, что именно нужно построить, график какой именно функции, но что касается Z^2=X^2+Y^2 могу объяснить.
Все дело снова в математике, а именно в области определения функции:
Область определения D(Z) = R, т.е. от -бесконечности до +бесконечности.
Это означает, что функция определена для любых Х, а в случае 3-х мерного графика и для любых Y. Поэтому для корректного отображения графика функции Z^2=X^2+Y^2 необходимо брать промежуток по X, Y равный скажем [-pole; +pole]. А ты в своем примере как-бы ограничиваешь поверхность координатными осями X и Y.

Ниже привожу рабочий пример для рисования графика функции Z^2=X^2+Y^2:
public void DrawFunction()
{
int prec_x = 50, prec_y = 50, i = 0, j = 0;
int pole = 10;
double[] X = new double[prec_x], Y = new double[prec_y];
double[,] Z = new double[prec_x, prec_y];

// Обрати внимание на условие цикла FOR
for (double x = -pole; Math.Round(x, 4) < pole;
x += (double)pole*2 / (double)prec_x)
{
j = 0;
X[i] = x;

// Обрати внимание на условие цикла FOR
for (double y = -pole; Math.Round(y, 4) < pole;
y += (double)pole*2 / (double)prec_y)
{
Y[j] = y;
// Ф-ция поверхности, которую будем отображать;
//Z[i, j] = SinSin(X[i], Y[j]);
Z[i, j] = Xpow2_Ypow2(X[i], Y[j]);
j++;
}
i++;
}
// DRAWING.
double r, g, b;
r = g = b = 1.0f;
for (i = 0; i < prec_x - 1; i++)
{
r = 1.0f;
for (j = 0; j < prec_y - 1; j++)
{
// Рисуем поверхность треугольниками;
Gl.glColor3d(r, g, b);
Gl.glBegin(Gl.GL_TRIANGLES);
// 1
Gl.glVertex3d(X[i], Z[i, j], Y[j]);
Gl.glVertex3d(X[i], Z[i, j + 1], Y[j + 1]);
Gl.glVertex3d(X[i + 1], Z[i + 1, j], Y[j]);
// 2
Gl.glVertex3d(X[i], Z[i, j + 1], Y[j + 1]);
Gl.glVertex3d(X[i + 1], Z[i + 1, j], Y[j]);
Gl.glVertex3d(X[i + 1], Z[i + 1, j + 1], Y[j + 1]);
// End
Gl.glEnd();
r -= 1.0 / prec_y;
}
g -= 1.0 / prec_x;
}
}

// Функция Z^2 = X^2 + Y^2;
private double Xpow2_Ypow2(double x, double y)
{
// z = Math.Sqrt((x*x + y*y));
return Math.Sqrt((x*x + y*y));
}

// Функция Z = sin(x)*sin(y);
private double SinSin(double x, double y)
{
// z = Math.Sin(x) * Math.Sin(y);
return Math.Sin(x) * Math.Sin(y);
}
При таких условиях в циклах FOR, получится следующее изображение:
^
Регистрация
Регистрируясь, вы принимаете правила сайта. Если вы не получили код подтв. регистрации - не забудьте проверить папку спам.
Логин*
Email*
Пароль*
Подтверждение пароля*
 
Логин*
Код*
 
×
Восстановление пароля
Пожалуйста, заполните поля, после чего вы получите код подтверждения на ваш Email. Если код не пришел в течении нескольких минут - проверьте папку спам.
Логин

или Email
Логин*
Код подтверждения*
Новый пароль*
Подтверждение пароля*
×
Авторизация
  • Используйте вашу учетную запись на Facebook.com для входа на сайт.
  • Используйте вашу учетную запись VKontakte для входа на сайт.
  • Используйте вашу учетную запись Google для входа на сайт.
Авторизуйтесь с помощью соц. сети или с помощью аккаунта на сайте:
×