Skip to content

Commit 7fd4765

Browse files
committed
fix calculate area bug by Chebyshev.
1 parent 29c7338 commit 7fd4765

File tree

4 files changed

+65
-7
lines changed

4 files changed

+65
-7
lines changed

src/LNLib/Algorithm/Integrator.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,63 @@ namespace LNLib
196196
}
197197
return integration;
198198
}
199+
double Integrator::ClenshawCurtisQuadrature2(IntegrationFunction& function, void* customData, double start, double end, std::vector<double> series, double epsilon)
200+
{
201+
double integration;
202+
int j, k, l;
203+
double err, esf, eref, erefh, hh, ir, iback, irback, ba, ss, x, y, fx, errir;
204+
int lenw = series.size() - 1;
205+
esf = 10;
206+
ba = 0.5 * (end - start);
207+
ss = 2 * series[lenw];
208+
x = ba * series[lenw];
209+
series[0] = 0.5 * (function)(start, customData);
210+
series[3] = 0.5 * (function)(end, customData);
211+
series[2] = (function)(start + x, customData);
212+
series[4] = (function)(end - x, customData);
213+
series[1] = (function)(start + ba, customData);
214+
eref = 0.5 * (fabs(series[0]) + fabs(series[1]) + fabs(series[2]) + fabs(series[3]) + fabs(series[4]));
215+
series[0] += series[3];
216+
series[2] += series[4];
217+
ir = series[0] + series[1] + series[2];
218+
integration = series[0] * series[lenw - 1] + series[1] * series[lenw - 2] + series[2] * series[lenw - 3];
219+
erefh = eref * sqrt(epsilon);
220+
eref *= epsilon;
221+
hh = 0.25;
222+
l = 2;
223+
k = lenw - 5;
224+
do {
225+
iback = integration;
226+
irback = ir;
227+
x = ba * series[k + 1];
228+
y = 0;
229+
integration = series[0] * series[k];
230+
for (j = 1; j <= l; j++) {
231+
x += y;
232+
y += ss * (ba - x);
233+
fx = (function)(start + x, customData) + (function)(end - x, customData);
234+
ir += fx;
235+
integration += series[j] * series[k - j] + fx * series[k - j - l];
236+
series[j + l] = fx;
237+
}
238+
ss = 2 * series[k + 1];
239+
err = esf * l * fabs(integration - iback);
240+
hh *= 0.25;
241+
errir = hh * fabs(ir - 2 * irback);
242+
l *= 2;
243+
k -= l + 2;
244+
} while ((err > erefh || errir > eref) && k > 4 * l);
245+
integration *= end - start;
246+
if (err > erefh || errir > eref)
247+
{
248+
err *= -fabs(end - start);
249+
}
250+
else
251+
{
252+
err = eref * fabs(end - start);
253+
}
254+
return integration;
255+
}
199256
}
200257

201258

src/LNLib/Geometry/Surface/NurbsSurface.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ namespace LNLib
6666
AreaCoreFunction areaCoreFunction;
6767
AreaData* data = (AreaData*)customData;
6868
data->ParameterV = parameter;
69-
return Integrator::ClenshawCurtisQuadrature(areaCoreFunction, data, data->CurrentKnotU, data->NextKnotU, series);
69+
return Integrator::ClenshawCurtisQuadrature2(areaCoreFunction, data, data->CurrentKnotU, data->NextKnotU, data->Series);
7070
}
7171
};
7272

@@ -2913,10 +2913,10 @@ double LNLib::NurbsSurface::ApproximateArea(const LN_NurbsSurface& surface, Inte
29132913
data.NextKnotU = knotVectorU[i + 1];
29142914
for (int j = degreeV; j < controlPoints[0].size(); j++)
29152915
{
2916-
data.CurrentKnotV = knotVectorV[i];
2917-
data.NextKnotV = knotVectorV[i + 1];
2916+
data.CurrentKnotV = knotVectorV[j];
2917+
data.NextKnotV = knotVectorV[j + 1];
29182918

2919-
area += Integrator::ClenshawCurtisQuadrature(function, (void*)&data, data.CurrentKnotV, data.NextKnotV, series);
2919+
area += Integrator::ClenshawCurtisQuadrature2(function, (void*)&data, data.CurrentKnotV, data.NextKnotV, series);
29202920
}
29212921
}
29222922
break;

src/LNLib/include/Integrator.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ namespace LNLib
3939
/// According to https://github.com/chrisidefix/nurbs
4040
/// </summary>
4141
static std::vector<double> ChebyshevSeries(int size = 100);
42-
static double ClenshawCurtisQuadrature(IntegrationFunction& function, void* customData, double start, double end, std::vector<double>& series, double epsilon = Constants::DistanceEpsilon);
42+
static double ClenshawCurtisQuadrature(IntegrationFunction& function, void* customData, double start, double end, std::vector<double>& series, double epsilon = Constants::DistanceEpsilon);
43+
static double ClenshawCurtisQuadrature2(IntegrationFunction& function, void* customData, double start, double end, std::vector<double> series, double epsilon = Constants::DistanceEpsilon);
4344
};
4445
}
4546

tests/T_Additional.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ TEST(Test_Additional, Area)
119119

120120
double simpson = NurbsSurface::ApproximateArea(surface, IntegratorType::Simpson);
121121
double gaussLegendre = NurbsSurface::ApproximateArea(surface, IntegratorType::GaussLegendre);
122+
double chebyshev = NurbsSurface::ApproximateArea(surface, IntegratorType::Chebyshev);
122123
EXPECT_FALSE(MathUtils::IsAlmostEqualTo(simpson, standardArea)); // not accuracy when use Simpson
123124
EXPECT_TRUE(MathUtils::IsAlmostEqualTo(gaussLegendre, standardArea));
124-
//Need fix, to be continued...
125-
//double chebyshev = NurbsSurface::ApproximateArea(surface, IntegratorType::Chebyshev);
125+
EXPECT_TRUE(MathUtils::IsAlmostEqualTo(chebyshev, standardArea));
126126
}

0 commit comments

Comments
 (0)