2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 сечение трехмерной фигуры
Сообщение10.04.2010, 20:05 
Фигура задана треугольниками, вершины которых зачитаны в структуру s. Эта структура имеет три поля A,B,C типа Vector3D. A,B,C --- хранят вершины треугольников. Помогите найти устранить проблему в коде: линия, изображающая сечение, получается с "дырками" (т.е. отсутствующими отрезками).

Код:
std::ofstream fsec("sec");
int i;
Vector3D M, N,  X;
for(i=0; i<nGt; ++i){
    M = s[i].A;
    N = s[i].B;
    // (X.x-N.x)/(M.x-N.x)=(0.0-N.y)/(M.y-N.y) => X.x=N.x-N.y*(M.x-N.x)/(M.y-N.y)
    // (X.z-N.z)/(M.z-N.z)=(0.0-N.y)/(M.y-N.y) => X.z=N.z-N.y*(M.z-N.z)/(M.y-N.y)
    if(fabs(M.y)<eps&&fabs(N.y)<eps) {
       fsec<<M.x<<' '<<M.z<<std::endl<<N.x<<' '<<N.z<<std::endl;
    }   else if( ((M.y<=0.0)&&(N.y>=0.0)) || ((M.y>=0.0)&&(N.y<=0.0)) ) {
        X.x=N.x-N.y*(M.x-N.x)/(M.y-N.y);
        X.z=N.z-N.y*(M.z-N.z)/(M.y-N.y);
        fsec << X.x << ' ' << X.z << std::endl ;
    }

    M = sigma_t[i].B;
    N = sigma_t[i].C;
   // аналогично

    M = sigma_t[i].C;
    N = sigma_t[i].A;
   // аналогично

 
 
 
 Re: сечение трехмерной фигуры
Сообщение12.04.2010, 14:49 
Для задания фигуры недостаточно знать одни лишь координаты вершин - надо еще знать тройки вершин, образующих треугольники.
И даже это не гарантирует что заданная поверхность будет замкнутой.
Иными словами надо смотреть не только на код но и на входные данные.

 
 
 
 Re: сечение трехмерной фигуры
Сообщение12.04.2010, 23:12 
Roman Voznyuk в сообщении #308753 писал(а):
Для задания фигуры недостаточно знать одни лишь координаты вершин - надо еще знать тройки вершин, образующих треугольники.
И даже это не гарантирует что заданная поверхность будет замкнутой.


извиняюсь, не понял. Чем отличаются координаты трех вершин треугольника от "тройки вершин, образующих треугольники" ?

Roman Voznyuk в сообщении #308753 писал(а):
Иными словами надо смотреть не только на код но и на входные данные.


нарисовал эллипсоид.

Изображение

Изображение

его сечение получается таким

Изображение

три отрезка отсутствуют.

 
 
 
 Re: сечение трехмерной фигуры
Сообщение13.04.2010, 00:42 
d.dragon.n76 в сообщении #308880 писал(а):

извиняюсь, не понял. Чем отличаются координаты трех вершин треугольника от "тройки вершин, образующих треугольники" ?

Каждая вершина принадлежит нескольким треугольникам.
В итоге вашим методом получается не замкнутая фигура, а набор независимых друг от друга отрезков.

d.dragon.n76 в сообщении #308880 писал(а):
три отрезка отсутствуют.

И один лишний.

Расскажите что именно вы делаете, а то из вашего кода непонятно.
Вообще говоря вам ничего не остается кроме как проверять каждую пару вершин на предмет того лежат ли они по разные стороны плоскости путем подстановки в уравнение плоскости, и если лежат то искать точки пересечения.

 
 
 
 Re: сечение трехмерной фигуры
Сообщение13.04.2010, 07:57 
Roman Voznyuk в сообщении #308912 писал(а):
Расскажите что именно вы делаете, а то из вашего кода непонятно.
Вообще говоря вам ничего не остается кроме как проверять каждую пару вершин на предмет того лежат ли они по разные стороны плоскости путем подстановки в уравнение плоскости, и если лежат то искать точки пересечения.


Поверхность состоит из независимых треугольников и в общем случае имеет разрывы. Но, сейчас я тестирую код на непрерывных поверхностях.

Строим сечение плоскостью $xOz$. Рассматриваю каждый отрезок $NM$, образующий треугольник. Если координата $y$ равна нулю с точностью до значения переменной eps (кстати взял слишком большой, потому и лишний отрезок появился) , то я просто сохраняю отрезок в файл:
Код:
if(fabs(M.y)<eps&&fabs(N.y)<eps) {
       fsec<<M.x<<' '<<M.z<<std::endl<<N.x<<' '<<N.z<<std::endl;
}


Далее, возможна ситуация когда отрезок пересекает плоскость $xOz$, тогда я нахожу точку пересечения и сохраняю ее в файл:
Код:
}   else if( ((M.y<=0.0)&&(N.y>=0.0)) || ((M.y>=0.0)&&(N.y<=0.0)) ) {
        X.x=N.x-N.y*(M.x-N.x)/(M.y-N.y);
        X.z=N.z-N.y*(M.z-N.z)/(M.y-N.y);
        fsec << X.x << ' ' << X.z << std::endl ;
}

Здесь же предусмотрен случай, когда треугольник касается секущей плоскости одной точкой (вершиной).

 
 
 
 Re: сечение трехмерной фигуры
Сообщение13.04.2010, 14:33 
d.dragon.n76 в сообщении #308946 писал(а):
Здесь же предусмотрен случай, когда треугольник касается секущей плоскости одной точкой (вершиной).

Зато не предусмотрен если отрезок параллелен плоскости $XOZ$.
Деление на нуль у вас будет.
Кроме того, почему вы принадлежность конца отрезка проверяете с точностью до погрешности, а пересечение с плоскостью сравниваете абсолютно?

 
 
 
 Re: сечение трехмерной фигуры
Сообщение13.04.2010, 15:16 
Roman Voznyuk в сообщении #309023 писал(а):
Зато не предусмотрен если отрезок параллелен плоскости $XOZ$.
Деление на нуль у вас будет.


первый участок кода реагирует на случай, когда отрезок лежит в плоскости $xOz$. Поэтому во втором участке кода деление на ноль не возникает, т.е. $M.y\not=N.y$.

Roman Voznyuk в сообщении #309023 писал(а):
Кроме того, почему вы принадлежность конца отрезка проверяете с точностью до погрешности, а пересечение с плоскостью сравниваете абсолютно?


С точностью до эпсилон я сравниваю с нулем, так как в переменной типа double точно 0 никогда не будет, а может сидеть машинный ноль. Когда я смотрю больше или меньше нуля, то либо больше нуля либо меньше без всяких приближений :-) .

Нужно осмыслить случай когда одна точка попадает в сечение ... Ее вообще не нужно отлавливать! Отсутствие точки на графике не будет заметным.

 
 
 [ Сообщений: 7 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group