
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.21] |
![]() |
|
![]() |
Сообщ.
#1
,
|
|
Треугольник и отрезок задаются координатами трех вершин и обоих концов.
В тырнете всё какое-то побитое |
Сообщ.
#2
,
|
|
|
![]() |
Сообщ.
#3
,
|
|
Спасибо, но бяка в том, что в этом коде есть ссылки на Normalize() и непонятное RDOT
|
Сообщ.
#4
,
|
|
|
Ищешь точку пересечения отрезка и плоскости треугольника. Потом проверяешь, лежит ли точка внутри треугольника. Если отрезок лежит в плоскости треугольника отсекаешь треугольник сторонами.
|
Сообщ.
#5
,
|
|
|
По логике
Цитата darcus @ Normalize() Это нормировка Цитата darcus @ RDOT Преобразование градусов в радианы Но описания их мне найти не удалось ![]() |
Сообщ.
#6
,
|
|
|
Цитата kanes @ Опять же по логике, это приведение к единичной длине:По логике Цитата (darcus @ Вчера, 22:24) Normalize() Это нормировка ![]() ![]() void Normalise( XYZ* p) { double r = sqrt( p->x * p->x + p->y * p->y + p->z * p->z ); p->x /= r; p->y /= r; p->z /= r; //неплохо бы еще проверить на 0. } RDOT я там не увидел, есть RTOD, опять же по логике (Radians TO Degrees) это константа перевода радиан в градусы ![]() ![]() const double RTOD = 180. / M_PI; |
Сообщ.
#7
,
|
|
|
Adil, во, я затупил что-то, ты прав
|
![]() |
Сообщ.
#8
,
|
|
thanx guys
вот что получилось: ![]() ![]() #include <cmath> #include <cstdio> #include <cstdlib> using namespace std; typedef struct XYZ {double x; double y; double z;}; const double M_PI = 3.14159265358979323846; const double RTOD = 180. / M_PI; const double EPS = 1.0E-9; void Normalize(XYZ* p) { double r; r = sqrt(p->x * p->x + p->y * p->y + p->z * p->z); p->x /= r; p->y /= r; p->z /= r; } bool LineFacet(XYZ p1, XYZ p2, XYZ pa, XYZ pb, XYZ pc, XYZ* p) { double d; double a1, a2, a3; double total, denom, mu; XYZ n, pa1, pa2, pa3; n.x = (pb.y - pa.y) * (pc.z - pa.z) - (pb.z - pa.z) * (pc.y - pa.y); n.y = (pb.z - pa.z) * (pc.x - pa.x) - (pb.x - pa.x) * (pc.z - pa.z); n.z = (pb.x - pa.x) * (pc.y - pa.y) - (pb.y - pa.y) * (pc.x - pa.x); Normalize(&n); d = - n.x * pa.x - n.y * pa.y - n.z * pa.z; denom = n.x * (p2.x - p1.x) + n.y * (p2.y - p1.y) + n.z * (p2.z - p1.z); if (abs(denom) < EPS) return false; mu = - (d + n.x * p1.x + n.y * p1.y + n.z * p1.z) / denom; p->x = p1.x + mu * (p2.x - p1.x); p->y = p1.y + mu * (p2.y - p1.y); p->z = p1.z + mu * (p2.z - p1.z); if (mu < 0 || mu > 1) return false; pa1.x = pa.x - p->x; pa1.y = pa.y - p->y; pa1.z = pa.z - p->z; Normalize(&pa1); pa2.x = pb.x - p->x; pa2.y = pb.y - p->y; pa2.z = pb.z - p->z; Normalize(&pa2); pa3.x = pc.x - p->x; pa3.y = pc.y - p->y; pa3.z = pc.z - p->z; Normalize(&pa3); a1 = pa1.x * pa2.x + pa1.y * pa2.y + pa1.z * pa2.z; a2 = pa2.x * pa3.x + pa2.y * pa3.y + pa2.z * pa3.z; a3 = pa3.x * pa1.x + pa3.y * pa1.y + pa3.z * pa1.z; total = (acos(a1) + acos(a2) + acos(a3)) * RTOD; if (abs(total - 360) > EPS) return false; return true; } int main() { //#define fp stdin FILE* fp = fopen("D:\\LineFacet_test.txt", "wt"); XYZ t1, t2, t3, p1, p2, p; int cnt = 0; while (cnt < 5) { t1.x = (double)rand(); t1.y = (double)rand(); t1.z = (double)rand(); t2.x = (double)rand(); t2.y = (double)rand(); t2.z = (double)rand(); t3.x = (double)rand(); t3.y = (double)rand(); t3.z = (double)rand(); p1.x = (double)rand(); p1.y = (double)rand(); p1.z = (double)rand(); p2.x = (double)rand(); p2.y = (double)rand(); p2.z = (double)rand(); if (LineFacet(p1, p2, t1, t2, t3, &p)) { ++cnt; fprintf(fp, "%d:\n", cnt); fprintf(fp, "Triangle:\n"); fprintf(fp, "%.0lf %.0lf %.0lf\n", t1.x, t1.y, t1.z); fprintf(fp, "%.0lf %.0lf %.0lf\n", t2.x, t2.y, t2.z); fprintf(fp, "%.0lf %.0lf %.0lf\n\n", t3.x, t3.y, t3.z); fprintf(fp, "Line segment:\n"); fprintf(fp, "%.0lf %.0lf %.0lf\n", p1.x, p1.y, p1.z); fprintf(fp, "%.0lf %.0lf %.0lf\n\n", p2.x, p2.y, p2.z); fprintf(fp, "Point of intersection:\n"); fprintf(fp, "%.2lf %.2lf %.2lf\n\n", p.x, p.y, p.z); } } fclose(fp); system("pause"); return 0; } Т.е. проверяем случайно выбранные пары "Треугольник - Отрезок". Образец выхода: ![]() ![]() 1: Triangle: 8281 4734 53 1999 26418 27938 6900 3788 18127 Line segment: 467 3728 14893 24648 22483 17807 Point of intersection: 6314.27 8263.20 15597.64 2: Triangle: 6038 24179 18190 29657 7958 6191 19815 22888 19156 Line segment: 11511 16202 2634 24272 20055 20328 Point of intersection: 20818.91 19012.39 15540.05 3: Triangle: 22646 26362 4886 18875 28433 29869 20142 23844 1416 Line segment: 21881 31998 10322 18651 10021 5699 Point of intersection: 20992.43 25952.14 9050.22 4: Triangle: 8313 4474 28022 2168 14018 18787 9905 17958 7391 Line segment: 10202 3625 26477 4414 9314 25824 Point of intersection: 7776.84 6008.68 26203.39 5: Triangle: 23216 1626 9357 8526 13357 29337 23271 23869 29361 Line segment: 12896 13022 29617 10112 12717 18696 Point of intersection: 12138.62 12939.03 26645.98 Во вложении 2000 блоков из якобы имеющих общую точку пар "треугольник-отрезок". Формат блока: первые 3 строки - треугольник, потом 2 - отрезок, 6-я строка - найденная точка пересечения. Может у кого будет желание проверить другим кодом. Прикреплённый файл ![]() |
![]() |
Сообщ.
#9
,
|
|
Скорее всего код сверху не достаточно корректен. Потому что другой, независимый, код забраковал 1564 случаев из 2000 ( в моем файле ) как No intersection! Например такую пару: ![]() ![]() X Y Z 6038 24179 18190 ------ треугольник 29657 7958 6191 19815 22888 19156 11511 16202 2634 ------ отрезок 24272 20055 20328 Упс! Я же умудрился забыть, при чтении из файла, пропускать каждую 6-ю строку (в которой координаты точки пересечения). Поэтому и случилось несоответствие. Перепроверил - полное совпадение. Проверил еще на других 5000 парах, тоже полное совпадение. Похоже, функция LineFacet() работает 100% корректно. P.S. Мой другой, контрольный, код только тестирует на существование пересечения; саму точку пересечения он не ищет. |