30 #define Pred(x) ((x)->prev)
31 #define Succ(x) ((x)->next)
38 if(p ==
nullptr)
return -1;
41 }
while(p !=
points[a].adjacent);
51 if(p ==
nullptr)
return -1;
54 }
while(p !=
points[a].adjacent);
62 if(p ==
nullptr)
return 0;
73 }
while((p !=
copy) && !out);
79 return (
points[
x].adjacent)->point_num;
160 if((h == i) && (h == j) && (h == k)) {
161 throw std::runtime_error(
"Identical points in triangulation: "
162 "increase element size or Mesh.RandomFactor");
175 return (result < 0) ? 1 : 0;
189 while((l != ut.
from) || (r != ut.
to)) {
191 if(!
Insert(l, r))
return 0;
194 if(r1 == -1)
return 0;
201 if(r2 == -1)
return 0;
204 else if(
Qtest(l, r, r1, r2))
207 if(!
Delete(r, r1))
return 0;
215 if(l1 == -1)
return 0;
222 if(l2 == -1)
return 0;
225 else if(
Qtest(r, l, l1, l2))
228 if(!
Delete(l, l1))
return 0;
240 if(
Qtest(l, r, r1, l1))
246 if(!
Insert(l, r))
return 0;
260 n = right - left + 1;
290 m = (left + right) >> 1;
303 return (y < 0.) ? -1 : 1;
306 return (x < 0.) ? -1 : 1;
322 double alpha1, alpha, beta, xx, yy;
329 if(*dlist ==
nullptr) {
335 if(
Succ(*dlist) == *dlist) {
352 yy = (double)(
points[first].where.v - center.
v);
353 xx = (double)(
points[first].where.h - center.
h);
354 alpha1 = atan2(yy, xx);
357 yy = (double)(
points[newPoint].where.v - center.
v);
358 xx = (double)(
points[newPoint].where.h - center.
h);
359 beta = atan2(yy, xx) - alpha1;
360 if(beta <= 0) beta += 2. * M_PI;
365 alpha = atan2(yy, xx) - alpha1;
366 if(alpha <= -1.e-15 ||
Succ(p)->point_num == first)
368 else if(abs(alpha) <= 1e-15 &&
371 if(alpha >= beta + 1e-15) {
378 else if(alpha >= beta - 1e-15) {
398 }
while(p != *dlist);
417 if(*dlist ==
nullptr)
return 0;
418 if(
Succ(*dlist) == *dlist) {
419 if((*dlist)->point_num == oldPoint) {
432 if(p == *dlist) { *dlist =
Succ(p); }
437 }
while(p != *dlist);
457 if(
points[0].adjacent ==
nullptr)
return 0;
461 while((p2 != 0) && (i < n)) {
467 return (i <= n) ? i : -1;
475 if(
points[0].adjacent ==
nullptr)
return;
480 while((p2 != 0) && (count <
numPoints)) {
498 }
while(p != *dlist);
500 if(ptr ==
nullptr)
return nullptr;
502 for(i = 0; i < max; i++) {
541 for(
int j = 0; j < n; j++) {
549 pts.push_back(
SPoint2(center[0], center[1]));
574 FILE *
f =
Fopen(fileName.c_str(),
"w");
576 Msg::Error(
"Could not open file '%s'", fileName.c_str());
580 fprintf(
f,
"View \"voronoi\" {\n");
582 std::vector<SPoint2> pts;
585 GPoint p0(pc[0], pc[1], 0.0);
587 fprintf(
f,
"SP(%g,%g,%g){%g};\n", p0.
x(), p0.
y(), p0.
z(), (
double)i);
589 for(std::size_t j = 0; j < pts.size(); j++) {
591 SPoint2 pp2 = pts[(j + 1) % pts.size()];
598 fprintf(
f,
"SL(%g,%g,%g,%g,%g,%g){%g,%g};\n", p1.
x(), p1.
y(), p1.
z(),
599 p2.
x(), p2.
y(), p2.
z(), (
double)i, (
double)i);
603 fprintf(
f,
"SP(%g,%g,%g){%g};\n", pc[0], pc[1], 0., -(
double)i);
609 fprintf(
f,
"View \"scalar\" {\n");
613 std::vector<PointNumero> adjacentPoints;
617 }
while(p !=
points[iPoint].adjacent);
620 for(
size_t iTriangle = 0; iTriangle < adjacentPoints.size() - 1;
622 const PointNumero jPoint = adjacentPoints[iTriangle];
623 const PointNumero kPoint = adjacentPoints[iTriangle + 1];
624 if((jPoint > iPoint) && (kPoint > iPoint) &&
626 fprintf(
f,
"ST(%g,%g,%g,%g,%g,%g,%g,%g,%g){%g,%g,%g};\n",
630 (
double)iPoint, (
double)jPoint, (
double)kPoint);
642 FILE *
f =
Fopen(fileName.c_str(),
"w");
644 Msg::Error(
"Could not open file '%s'", fileName.c_str());
648 fprintf(
f,
"View \"medial axis\" {\n");
650 std::vector<SPoint2> pts;
653 GPoint p0(pc[0], pc[1], 0.0);
654 if(gf) p0 = gf->
point(pc[0], pc[1]);
655 fprintf(
f,
"SP(%g,%g,%g){%g};\n", p0.
x(), p0.
y(), p0.
z(), (
double)i);
657 for(std::size_t j = 0; j < pts.size(); j++) {
659 SVector3 pp2(pts[(j + 1) % pts.size()].x(),
660 pts[(j + 1) % pts.size()].y(), 0.0);
666 p1 = gf->
point(p1.
x(), p1.
y());
667 p2 = gf->
point(p2.
x(), p2.
y());
669 double P1[3] = {p1.
x(), p1.
y(), p1.
z()};
670 double P2[3] = {p2.
x(), p2.
y(), p2.
z()};
679 fprintf(
f,
"SL(%g,%g,%g,%g,%g,%g){%g,%g};\n", p1.
x(), p1.
y(),
680 p1.
z(), p2.
x(), p2.
y(), p2.
z(), (
double)i, (
double)i);
691 double &xc,
double &yc,
double &inertia,
694 const int N = pts.size();
696 double sina = sin(
angle);
697 double cosa = cos(
angle);
699 double xmin = cosa * pts[0].x() + sina * pts[0].y();
700 double xmax = cosa * pts[0].x() + sina * pts[0].y();
701 double ymin = -sina * pts[0].x() + cosa * pts[0].y();
702 double ymax = -sina * pts[0].x() + cosa * pts[0].y();
703 for(
int j = 1; j < N; j++) {
704 xmin = std::min(cosa * pts[j].x() + sina * pts[j].y(), xmin);
705 ymin = std::min(-sina * pts[j].x() + cosa * pts[j].y(), ymin);
706 xmax = std::max(cosa * pts[j].x() + sina * pts[j].y(), xmax);
707 ymax = std::max(-sina * pts[j].x() + cosa * pts[j].y(), ymax);
709 double XC = 0.5 * (xmax + xmin);
710 double YC = 0.5 * (ymax + ymin);
711 xc = XC * cosa - YC * sina;
712 yc = XC * sina + YC * cosa;
713 inertia = std::max(xmax - xmin, ymax - ymin);
714 area = (xmax - xmin) * (ymax - ymin);
718 double &yc,
double &inertia,
double &areaCell,
724 for(std::size_t j = 0; j < pts.size(); j++) {
726 SPoint2 &pb = pts[(j + 1) % pts.size()];
728 const double lc = bgm ? (*bgm)((pa.
x() + pb.
x() + pc.
x()) / 3.0,
729 (pa.
y() + pb.
y() + pc.
y()) / 3.0, 0.0) :
731 const double fact = 1. / (lc * lc * lc * lc);
733 area_tot += area * fact;
734 center += ((pa + pb + pc) * (area * fact / 3.0));
736 SPoint2 x = center * (1.0 / area_tot);
738 for(std::size_t j = 0; j < pts.size(); j++) {
740 SPoint2 &pb = pts[(j + 1) % pts.size()];
743 const double b = sqrt((pa.
x() - pb.
x()) * (pa.
x() - pb.
x()) +
744 (pa.
y() - pb.
y()) * (pa.
y() - pb.
y()));
745 const double h = 2.0 * area / b;
746 const double a = fabs((pb.
x() - pa.
x()) * (pc.
x() - pa.
x()) *
747 (pb.
y() - pa.
y()) * (pc.
y() - pa.
y())) /
751 (h * b * b * b + h * a * b * b + h * a * a * b + b * h * h * h) / 12.0;
753 center = (pa + pb + pc) * (1.0 / 3.0);
755 inertia += j2 + area * area * (dx.
x() + dx.
x() + dx.
y() * dx.
y());
767 int count = 0, count2 = 0;
775 count2 = 2 * (n - 1) - count2;
780 for(i = 0; i < n; i++) {
789 for(i = 0; i < n; i++) {
790 for(j = 0; j < striangle[i].
t_length; j++) {
791 if((striangle[i].t[j] > i) && (striangle[i].t[j + 1] > i) &&
792 (
IsRightOf(i, striangle[i].t[j], striangle[i].t[j + 1]))) {
794 bb = striangle[i].
t[j];
795 cc = striangle[i].
t[j + 1];
805 for(
int i = 0; i < n; i++)
delete[] striangle[i].t;
818 if(
points[i].adjacent !=
nullptr) {
824 }
while(p !=
points[i].adjacent);
830 : _hullSize(0), _hull(nullptr), _adjacencies(nullptr), numPoints(n),
831 points(nullptr), numTriangles(0), triangles(nullptr)
850 if(
points[i].adjacent ==
nullptr)
return false;
878 throw std::runtime_error(
"Incompatible number of points");
879 for(
int i = 0; i < p->
size1(); i++) {
882 data(i) = (*p)(i, 2) < 0 ? (
void *)1 :
nullptr;
887 int iTriangle, std::set<int> &taggedTriangles,
888 std::map<std::pair<void *, void *>, std::pair<int, int> > &edgesToTriangles)
890 if(taggedTriangles.find(iTriangle) != taggedTriangles.end())
return;
892 taggedTriangles.insert(iTriangle);
899 for(
int j = 0; j < 3; j++) {
901 std::pair<void *, void *> ab =
902 std::make_pair(std::min(p[j]->
data, p[(j + 1) % 3]->
data),
903 std::max(p[j]->
data, p[(j + 1) % 3]->
data));
904 std::pair<int, int> &adj = (edgesToTriangles.find(ab))->second;
905 if(iTriangle == adj.first && adj.second != -1)
915 std::map<std::pair<void *, void *>, std::pair<int, int> > edgesToTriangles;
931 double k1 = ((
x * y2 - x2 *
y) - (x0 * y2 - x2 * y0)) / (x1 * y2 - x2 * y1);
933 -((
x * y1 - x1 *
y) - (x0 * y1 - x1 * y0)) / (x1 * y2 - x2 * y1);
934 if(k1 > 0.0 && k2 > 0.0 && k1 + k2 < 1.0) iFirst = i;
935 for(
int j = 0; j < 3; j++) {
936 std::pair<void *, void *> ab =
937 std::make_pair(std::min(p[j]->
data, p[(j + 1) % 3]->
data),
938 std::max(p[j]->
data, p[(j + 1) % 3]->
data));
939 auto it = edgesToTriangles.find(ab);
940 if(it == edgesToTriangles.end()) {
941 edgesToTriangles[ab] = std::make_pair(i, -1);
944 it->second.second = i;
948 std::set<int> taggedTriangles;
950 return taggedTriangles;
964 std::vector<GEdge *> list = gf->
edges();
966 for(
auto it1 = list.begin(); it1 != list.end(); it1++) {
970 vertex1 =
element->getVertex(0);
971 vertex2 =
element->getVertex(1);
980 }
catch(
const char *err) {
985 for(
auto it2 = set.begin(); it2 != set.end(); it2++) {
1004 for(std::size_t i = 0; i <
points[index1].
vicinity.size() - 1; i = i + 2) {
1005 if(
points[index1].vicinity[i] == dataA &&
1006 points[index1].vicinity[i + 1] == dataB) {
1009 else if(
points[index1].vicinity[i] == dataB &&
1010 points[index1].vicinity[i + 1] == dataA) {
1031 if(
points[index].flag == 0) {
1043 if(
points[i].flag == 0) { numPoints2++; }
1048 if(
points[i].flag == 0) {
1077 for(
int j = 0; j < num; j++) {
1089 std::vector<GEdge *>
const &list = gf->
edges();
1091 for(
auto it = list.begin(); it != list.end(); it++) {
1097 bool flag =
find_edge(vertex1, vertex2);
1098 if(!flag)
return false;