gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
decasteljau.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 //
6 // Contributed by J. Lambrechts
7 
8 #include <algorithm>
9 #include "decasteljau.h"
10 #include "SPoint3.h"
11 #include "SVector3.h"
12 
13 typedef struct {
14  SPoint3 p;
15  double t;
16  int next;
17 } sortedPoint;
18 
19 static int sortedPointInsert(const SPoint3 &p, const double t,
20  std::vector<sortedPoint> &pts, int pos)
21 {
22  sortedPoint pnt = {p, t, pts[pos].next};
23  pts.push_back(pnt);
24  int newp = (int)pts.size() - 1;
25  pts[pos].next = newp;
26  return newp;
27 }
28 
29 static void sortedPointToVector(const std::vector<sortedPoint> &spts,
30  std::vector<SPoint3> &pts,
31  std::vector<double> &ts)
32 {
33  pts.clear();
34  pts.reserve(spts.size());
35  ts.clear();
36  ts.reserve(spts.size());
37  for(int p = 0; p != -1; p = spts[p].next) {
38  pts.push_back(spts[p].p);
39  ts.push_back(spts[p].t);
40  }
41 }
42 
43 double sqDistPointSegment(const SPoint3 &p, const SPoint3 &s0,
44  const SPoint3 &s1)
45 {
46  SVector3 d(s1 - s0);
47  SVector3 d0(p - s0);
48  SVector3 d1(p - s1);
49  double dn2 = crossprod(d, d0).normSq();
50  double dt2 = std::max(0., std::max(-dot(d, d0), dot(d, d1)));
51  dt2 *= dt2;
52  return (dt2 + dn2) / d.normSq();
53 }
54 
55 static void decasteljau(double tol, std::vector<sortedPoint> &discrete, int pos,
56  const SPoint3 &p0, const SPoint3 &p1, const SPoint3 &p2,
57  double t0, double t2)
58 {
59  if(sqDistPointSegment(p1, p0, p2) < tol * tol) return;
60  SPoint3 p01((p0 + p1) * 0.5);
61  SPoint3 p12((p1 + p2) * 0.5);
62  SPoint3 p012((p01 + p12) * 0.5);
63  double t012 = 0.5 * (t0 + t2);
64  int newpos = sortedPointInsert(p012, t012, discrete, pos);
65  decasteljau(tol, discrete, pos, p0, p01, p012, t0, t012);
66  decasteljau(tol, discrete, newpos, p012, p12, p2, t012, t2);
67 }
68 
69 void decasteljau(double tol, const SPoint3 &p0, const SPoint3 &p1,
70  const SPoint3 &p2, std::vector<SPoint3> &pts,
71  std::vector<double> &ts)
72 {
73  std::vector<sortedPoint> discrete;
74  sortedPoint pnt1 = {p0, 0., 1};
75  discrete.push_back(pnt1);
76  sortedPoint pnt2 = {p2, 1., -1};
77  discrete.push_back(pnt2);
78  decasteljau(tol, discrete, 0, p0, p1, p2, 0., 1);
79  sortedPointToVector(discrete, pts, ts);
80 }
81 
82 static void decasteljau(double tol, std::vector<sortedPoint> &discrete, int pos,
83  const SPoint3 &p0, const SPoint3 &p1, const SPoint3 &p2,
84  const SPoint3 &p3, double t0, double t3)
85 {
86  if(std::max(sqDistPointSegment(p1, p0, p3), sqDistPointSegment(p2, p0, p3)) <
87  tol * tol)
88  return;
89  SPoint3 p01((p0 + p1) * 0.5);
90  SPoint3 p12((p1 + p2) * 0.5);
91  SPoint3 p23((p2 + p3) * 0.5);
92  SPoint3 p012((p01 + p12) * 0.5);
93  SPoint3 p123((p12 + p23) * 0.5);
94  SPoint3 p0123((p012 + p123) * 0.5);
95  double t0123 = 0.5 * (t0 + t3);
96  int newpos = sortedPointInsert(p0123, t0123, discrete, pos);
97  decasteljau(tol, discrete, pos, p0, p01, p012, p0123, t0, t0123);
98  decasteljau(tol, discrete, newpos, p0123, p123, p23, p3, t0123, t3);
99 }
100 
101 void decasteljau(double tol, const SPoint3 &p0, const SPoint3 &p1,
102  const SPoint3 &p2, const SPoint3 &p3,
103  std::vector<SPoint3> &pts, std::vector<double> &ts)
104 {
105  std::vector<sortedPoint> discrete;
106  sortedPoint pnt1 = {p0, 0., 1};
107  discrete.push_back(pnt1);
108  sortedPoint pnt2 = {p3, 1., -1};
109  discrete.push_back(pnt2);
110  decasteljau(tol, discrete, 0, p0, p1, p2, p3, 0., 1);
111  sortedPointToVector(discrete, pts, ts);
112 }
113 
114 static void decasteljau(double tol, std::vector<sortedPoint> &discrete, int pos,
115  const std::vector<SPoint3> &pts, double t0, double te)
116 {
117  int order = (int)pts.size() - 1;
118  double dmax2 = 0;
119  for(int i = 1; i < order; ++i)
120  dmax2 = std::max(dmax2, sqDistPointSegment(pts[i], pts[0], pts[order]));
121  if(dmax2 < tol * tol) return;
122  std::vector<SPoint3> sub0(pts.size());
123  std::vector<SPoint3> sub1(pts);
124  for(int l = 0; l < order + 1; ++l) {
125  sub0[l] = sub1[0];
126  for(int i = 0; i < order - l; ++i) sub1[i] = (sub1[i] + sub1[i + 1]) * 0.5;
127  }
128  double tmid = 0.5 * (t0 + te);
129  int newpos = sortedPointInsert(sub1[0], tmid, discrete, pos);
130  decasteljau(tol, discrete, pos, sub0, t0, tmid);
131  decasteljau(tol, discrete, newpos, sub1, tmid, te);
132 }
133 
134 void decasteljau(double tol, const std::vector<SPoint3> &controlPoints,
135  std::vector<SPoint3> &pts, std::vector<double> &ts)
136 {
137  std::vector<sortedPoint> discrete;
138  sortedPoint pnt1 = {controlPoints[0], 0., 1};
139  discrete.push_back(pnt1);
140  sortedPoint pnt2 = {controlPoints.back(), 1., -1};
141  discrete.push_back(pnt2);
142  decasteljau(tol, discrete, 0, controlPoints, 0., 1);
143  sortedPointToVector(discrete, pts, ts);
144 }
decasteljau
static void decasteljau(double tol, std::vector< sortedPoint > &discrete, int pos, const SPoint3 &p0, const SPoint3 &p1, const SPoint3 &p2, double t0, double t2)
Definition: decasteljau.cpp:55
crossprod
SVector3 crossprod(const SVector3 &a, const SVector3 &b)
Definition: SVector3.h:150
dot
double dot(const SVector3 &a, const SMetric3 &m, const SVector3 &b)
Definition: STensor3.h:71
SVector3::normSq
double normSq() const
Definition: SVector3.h:34
sqDistPointSegment
double sqDistPointSegment(const SPoint3 &p, const SPoint3 &s0, const SPoint3 &s1)
Definition: decasteljau.cpp:43
SPoint3
Definition: SPoint3.h:14
SVector3
Definition: SVector3.h:16
SVector3.h
sortedPointInsert
static int sortedPointInsert(const SPoint3 &p, const double t, std::vector< sortedPoint > &pts, int pos)
Definition: decasteljau.cpp:19
sortedPointToVector
static void sortedPointToVector(const std::vector< sortedPoint > &spts, std::vector< SPoint3 > &pts, std::vector< double > &ts)
Definition: decasteljau.cpp:29
SPoint3.h
sortedPoint
Definition: GEdge.cpp:737
decasteljau.h