52 double a_mean_spacing,
53 double a_minimumCurvature = 0.001,
54 bool a_smooth =
false);
58 double a_minimumCurvature,
64 void GetParameterIFM(
double a_param,
double a_interval,
double& a_ti,
double& a_tm,
double& a_tf);
116 double a_featureSize,
117 double a_meanSpacing,
118 double a_minimumCurvature,
124 int numPoints = int(
m_length / a_meanSpacing);
127 return PlacePoints(a_featureSize, numPoints, a_minimumCurvature, a_smooth);
147 for (
size_t i = 0; i <
m_points.size() - 1; ++i)
149 const Pt3d& p0 = a_points[i];
150 const Pt3d& p1 = a_points[i + 1];
151 double length =
Mdist(p0.
x, p0.
y, p1.
x, p1.
y);
173 double a_minimumCurvature,
200 double a_minimumCurvature)
210 double interval = a_featureSize /
m_length;
218 curv = std::max(a_minimumCurvature, fabs(curv));
230 double sumDistance(0.0);
232 double halfFeatureSize = a_featureSize / 2.0;
233 for (
size_t i = 0; i <
m_points.size() - 1; ++i)
239 if (delta_d > a_featureSize)
252 sumDistance += delta_d;
290 double t = std::min(1.0, std::max(0.0, a_param));
292 auto it =
m_distMap.lower_bound(station);
304 if (d0 <= station && station <= d1)
306 double fraction = (station - d0) / (d1 - d0);
310 pt.
x = p0.
x + fraction * (p1.
x - p0.
x);
311 pt.
y = p0.
y + fraction * (p1.
y - p0.
y);
332 a_ti = a_param - a_interval;
333 a_tf = a_param + a_interval;
340 a_tm = 0.5 * (a_ti + a_tf);
345 a_tm = 0.5 * (a_ti + a_tf);
370 for (
size_t i = 1; i < shiftedCurvature.size() - 1; ++i)
375 shiftedParametricDistance[i] = p;
376 shiftedCurvature[i] = agg_curv;
378 shiftedParametricDistance.back() = 1.0;
379 shiftedCurvature.back() = agg_curv;
396 double p_a(pdist[idxA]), p_c(pdist[idxC]);
397 double curv_a(curve[idxA]), curv_b(curve[idxB]);
398 double s_ab(1.0 - p_a);
400 double proportion = s_ab / (s_ab + s_bc);
402 double curv_0 = curv_a + proportion * (curv_b - curv_a);
404 VecDbl shiftedPdist(pdist.size() + 1);
405 VecDbl shiftedCurve(curve.size() + 1);
406 shiftedCurve[0] = curv_0;
407 for (
size_t i = 1; i < shiftedPdist.size() - 1; ++i)
409 double p(0.5 * (pdist[i - 1] + pdist[i]));
411 shiftedCurve[i] = curve[i - 1];
413 shiftedPdist.back() = 1.0;
414 shiftedCurve.back() = curv_0;
417 VecDbl aggregatedCurve(shiftedCurve.size());
419 aggregatedCurve[0] = 0.0;
423 double deltaCurvature = shiftedCurve[1] - shiftedCurve[0];
424 aggregatedCurve[1] = deltaCurvature;
425 double agg_curv(aggregatedCurve[1]);
426 for (
size_t i = 2; i < shiftedCurve.size(); ++i)
428 agg_curv += shiftedCurve[i];
429 aggregatedCurve[i] = agg_curv;
448 for (
size_t i = 1; i < n; ++i)
451 smoothCurve[i] = smooth_curv;
464 double delta_threshold =
m_curvature.back() / (a_numPoints - 1);
465 double tol(1e-9), sumDelta(0);
466 for (
int i = 0; i < a_numPoints - 1; ++i)
468 sumDelta += delta_threshold;
471 double threshold(0.0);
476 for (
size_t i = 0; i < n; ++i)
488 while (
LT_TOL(threshold, c1, tol))
490 double t = (threshold - c0) / (c1 - c0);
491 double p = p0 + t * (p1 - p0);
493 result.push_back(pt);
494 threshold += delta_threshold;
544 VecPt3d pts = {{0, 0, 0}, {5, 5, 0}, {10, 10, 0}, {15, 5, 0}, {20, 10, 0}, {25, 0, 0}};
551 VecDbl expectedAccumulatedSegmentLengths = {0.0, 7.071, 14.142, 21.213, 28.284, 0};
554 double expectedLength(39.464);
555 TS_ASSERT_DELTA(expectedLength, r.
m_length, tol);
557 TS_ASSERT(
true == r.
m_open);
561 VecDbl expectedSegmentLengths = {7.071, 7.071, 7.071, 7.071, 11.180, 0};
564 double expectTolerance(2.6925824035672520e-008);
565 TS_ASSERT_DELTA(expectTolerance, r.
m_tol, 1e-7);
568 pts.push_back(pts.front());
574 VecDbl expectedAccumulatedSegmentLengths = {0.0, 7.071, 14.142, 21.213, 28.284, 39.464, 0};
577 double expectedLength(64.464);
578 TS_ASSERT_DELTA(expectedLength, r.
m_length, tol);
580 TS_ASSERT(
false == r.
m_open);
584 VecDbl expectedSegmentLengths = {7.071, 7.071, 7.071, 7.071, 11.180, 25.0, 0};
587 double expectTolerance(2.6925824035672520e-008);
588 TS_ASSERT_DELTA(expectTolerance, r.
m_tol, 1e-7);
608 VecPt3d pts = {{0, 0, 0}, {5, 5, 0}, {10, 10, 0}, {15, 5, 0}, {20, 10, 0}, {25, 0, 0}};
610 double featureSize(3.0);
614 VecDbl expectedParam = {0, 0.038, 0.141, 0.179, 0.217, 0.320, 0.358, 0.396,
615 0.500, 0.538, 0.576, 0.679, 0.717, 0.755, 0.962, 1};
617 VecDbl expectedCurvature = {-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1};
637 VecPt3d pts = {{0, 0, 0}, {5, 5, 0}, {10, 10, 0}, {15, 5, 0},
638 {20, 10, 0}, {21, 10, 0}, {25, 0, 0}};
640 double featureSize(3.0);
641 double minCurvature(0.001);
645 VecDbl expectedParam = {0, 0.037, 0.139, 0.177, 0.214, 0.316, 0.353, 0.391, 0.492,
646 0.530, 0.567, 0.669, 0.706, 0.719, 0.731, 0.769, 0.963, 1};
648 VecDbl expectedCurvature = {0.001, 0.000, 0.000, 0.001, 0.000, 0.000, 0.471, 0.000, 0.000,
649 0.471, 0.000, 0.000, 0.516, 0.000, 0.522, 0.000, 0.000, 0.001};
653 pts.push_back(pts.front());
658 VecDbl expectedParam = {0.000, 0.023, 0.086, 0.109, 0.132, 0.194, 0.217,
659 0.240, 0.303, 0.326, 0.349, 0.412, 0.435, 0.442,
660 0.450, 0.473, 0.593, 0.616, 0.639, 0.977, 1.000};
662 VecDbl expectedCurvature = {0.616, 0.000, 0.000, 0.001, 0.000, 0.000, 0.471,
663 0.000, 0.000, 0.471, 0.000, 0.000, 0.516, 0.000,
664 0.522, 0.000, 0.000, 0.552, 0.000, 0.000, 0.616};
684 VecPt3d pts = {{0, 0, 0}, {5, 5, 0}, {10, 10, 0}, {15, 5, 0},
685 {20, 10, 0}, {21, 10, 0}, {25, 0, 0}};
687 double featureSize(3.0);
688 double minCurvature(0.001);
693 VecDbl expectedParam = {0.000, 0.019, 0.088, 0.158, 0.195, 0.265, 0.334, 0.372, 0.441, 0.511,
694 0.548, 0.618, 0.687, 0.712, 0.725, 0.750, 0.866, 0.981, 1.000};
696 VecDbl expectedCurvature = {0.000, 0.001, 0.001, 0.001, 0.002, 0.002, 0.002,
697 0.473, 0.473, 0.473, 0.945, 0.945, 0.945, 1.461,
698 1.461, 1.983, 1.983, 1.983, 1.983};
718 VecPt3d pts = {{0, 0, 0}, {5, 5, 0}, {10, 10, 0}, {15, 5, 0},
719 {20, 10, 0}, {21, 10, 0}, {25, 0, 0}, {0, 0, 0}};
721 double featureSize(3.0);
722 double minCurvature(0.001);
727 VecDbl expectedParam = {0.000, 0.012, 0.054, 0.097, 0.120, 0.163, 0.206, 0.229,
728 0.272, 0.315, 0.338, 0.380, 0.423, 0.439, 0.446, 0.462,
729 0.533, 0.604, 0.627, 0.808, 0.988, 1.000};
731 VecDbl expectedCurvature = {0.000, 0.308, 0.308, 0.308, 0.309, 0.309, 0.309, 0.780,
732 0.780, 0.780, 1.252, 1.252, 1.252, 1.768, 1.768, 2.290,
733 2.290, 2.290, 2.842, 2.842, 2.842, 3.150};
753 VecPt3d pts = {{0, 0, 0}, {5, 5, 0}, {10, 10, 0}, {15, 5, 0},
754 {20, 10, 0}, {21, 10, 0}, {25, 0, 0}};
756 double featureSize(3.0);
757 double minCurvature(0.001);
764 VecDbl expectedParam = {0.000, 0.019, 0.088, 0.158, 0.195, 0.265, 0.334, 0.372, 0.441, 0.511,
765 0.548, 0.618, 0.687, 0.712, 0.725, 0.750, 0.866, 0.981, 1.000};
767 VecDbl expectedCurvature = {0.00000, 0.00075, 0.00100, 0.00125, 0.00175, 0.00200, 0.11985,
768 0.35555, 0.47340, 0.59126, 0.82696, 0.94481, 1.07384, 1.33190,
769 1.59154, 1.85277, 1.98338, 1.98338, 1.98338};
789 VecPt3d pts = {{0, 0, 0}, {5, 5, 0}, {10, 10, 0}, {15, 5, 0},
790 {20, 10, 0}, {21, 10, 0}, {25, 0, 0}};
792 double featureSize(3.0);
793 double minCurvature(0.001);
800 VecPt3d expectedPoints{{0, 0, 0}, {9.961, 9.961, 0}, {10.457, 9.543, 0},
801 {14.892, 5.108, 0}, {15.388, 5.388, 0}, {19.685, 9.685, 0},
802 {19.987, 9.987, 0}, {20.906, 10.000, 0}, {21.122, 9.695, 0},
811 VecPt3d expectedPoints{{0, 0, 0}, {9.922, 9.922, 0}, {11.954, 8.046, 0},
812 {14.784, 5.216, 0}, {16.442, 6.442, 0}, {19.546, 9.546, 0},
813 {20.213, 10.000, 0}, {20.656, 10.000, 0}, {21.151, 9.623, 0},
819 pts.push_back(pts.front());
826 VecPt3d expectedPoints{{0, 0, 0}, {9.562, 9.562, 0}, {10.350, 9.650, 0},
827 {15.077, 5.077, 0}, {19.673, 9.673, 0}, {20.216, 10.000, 0},
828 {21.143, 9.641, 0}, {24.883, 0.293, 0}, {24.364, 0.000, 0},
837 VecPt3d expectedPoints{{0, 0, 0}, {8.187, 8.187, 0}, {11.158, 8.842, 0},
838 {15.153, 5.153, 0}, {19.523, 9.523, 0}, {20.464, 10.000, 0},
839 {21.194, 9.515, 0}, {24.766, 0.586, 0}, {16.082, 0.000, 0},
849 std::string path(std::string(XMS_TEST_PATH) +
"redistribution/");
850 std::string infile(path +
"Coastline.txt"), outFile(path +
"Coastline_out.txt"),
851 baseFile(path +
"Coastline_base.txt");
853 is.open(infile, std::fstream::in);
858 is >> p.
x >> p.
y >> p.
z;
864 double featureSize(200.0), meanSpacing(50.0), minimumCurvature(.001);
865 bool smoothCurvature(
true);
866 pts = r.
Redistribute(pts, featureSize, meanSpacing, minimumCurvature, smoothCurvature);
870 std::fstream os(outFile, std::fstream::out);
873 os <<
STRstd(p.x, -1, width, flag) <<
" " <<
STRstd(p.y, -1, width, flag) <<
"\n";
883 std::string path(std::string(XMS_TEST_PATH) +
"redistribution/");
884 std::string infile(path +
"Island.txt"), outFile(path +
"Island_out.txt"),
885 baseFile(path +
"Island_base.txt");
887 is.open(infile, std::fstream::in);
892 is >> p.
x >> p.
y >> p.
z;
898 double featureSize(200.0), meanSpacing(50.0), minimumCurvature(.001);
899 bool smoothCurvature(
true);
900 pts = r.
Redistribute(pts, featureSize, meanSpacing, minimumCurvature, smoothCurvature);
904 std::fstream os(outFile, std::fstream::out);
907 os <<
STRstd(p.x, -1, width, flag) <<
" " <<
STRstd(p.y, -1, width, flag) <<
"\n";
VecDbl m_curvature
curvature at each point
Redistributes the point locations on a polyline or polygon based on curvature.
VecPt3d NewPointsFromParamCurvs(int a_numPoints)
Shifts half an interval and aggregates the curvature data in closed polygon.
void ShiftAndAggregateClosed()
Shifts half an interval and aggregates the curvature data in closed polygon.
VecPt3d PlacePoints(double a_featureSize, int a_numPoints, double a_minimumCurvature, bool a_smooth)
Redistribute points according to curvature.
bool gmCircumcircleWithTol(const Pt3d *pt1, const Pt3d *pt2, const Pt3d *pt3, double *xc, double *yc, double *r2, double tol)
void testSetup()
tests a simple case shown below
std::string STRstd(double a_value, int a_n, int width, int flags)
std::vector< double > VecDbl
void testNewPointsFromParamCurvs()
tests a simple case shown below
virtual VecPt3d Redistribute(const VecPt3d &a_points, double a_featureSize, double a_mean_spacing, double a_minimumCurvature=0.001, bool a_smooth=false)
Redistribute points according to curvature.
void testShiftAndAggregateClosed()
tests a simple case shown below
void CalculateCurvature(double a_featureSize, double a_minimumCurvature)
Calculates the curvature at the points where it has not yet been calculated.
std::map< double, int > m_distMap
map of distances and indices
VecDbl m_segmentLengths
length of each segment
VecPt3d m_points
locations defining polyline/polygon
double m_length
total length
Pt3d GetPointFromParameter(double a_param)
Get location based on parametric value a_param.
Redistributes the point locations on a polyline or polygon based on curvature.
void ShiftAndAggregateOpen()
Shifts half an interval and aggregates the curvature data in an open polyline.
void DoSmoothing(bool a_smooth)
Shifts half an interval and aggregates the curvature data in closed polygon.
double m_tol
tolerance used for geometric calculations
void testDoSmoothing()
tests a simple case shown below
void testCalculateCurvature()
tests a simple case shown below
#define XM_ENSURE_TRUE(...)
void testShiftAndAggregateOpen()
tests a simple case shown below
void GetSignificantPoints(double a_featureSize)
Redistribute points according to curvature.
bool m_open
false means polygon, true mean polyline
void GetParameterIFM(double a_param, double a_interval, double &a_ti, double &a_tm, double &a_tf)
Calculates the parameterized station values of the two point at each side of tc.
bool LT_TOL(_T A, _U B, _V tolerance)
static BSHP< MePolyRedistributePtsCurvature > New()
Creates an instance of this class.
void testGetSignificantPoints()
tests a simple case shown below
MePolyRedistributePtsCurvature()
constructor
double Mdist(_T x1, _U y1, _V x2, _W y2)
void Setup(const VecPt3d &)
sets up the class to do a Redistribute operation
void testCreateClass()
tests creating the class
virtual ~MePolyRedistributePtsCurvature()
destructor
VecDbl m_accumulatedSegmentLengths
accumulated length of polyline
void gmExtents2D(const VecPt3d &a_points, Pt2d &a_min, Pt2d &a_max)
VecDbl m_parametricDistance
distance (0-1) from starting to ending point
double GetCurvatureFromParameter(double a_param, double a_interval)
Redistribute points according to curvature.
std::vector< Pt3d > VecPt3d