CoastalME (Coastal Modelling Environment)
Simulates the long-term behaviour of complex coastlines
Loading...
Searching...
No Matches
calc_curvature.cpp
Go to the documentation of this file.
1
12
13/* ==============================================================================================================================
14
15 This file is part of CoastalME, the Coastal Modelling Environment.
16
17 CoastalME is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
23==============================================================================================================================*/
24#include <cfloat>
25
26#include <cmath>
27using std::sqrt;
28
29#include <numeric>
30using std::accumulate;
31using std::inner_product;
32
33#include "cme.h"
34#include "2d_point.h"
35#include "simulation.h"
36#include "coast.h"
37
38//===============================================================================================================================
40//===============================================================================================================================
41void CSimulation::DoCoastCurvature(int const nCoast, int const nHandedness)
42{
43 int const nCoastSize = m_VCoast[nCoast].nGetCoastlineSize();
44
45 // Start with detailed curvature, do every point on the coastline, apart from the first and last points
46 for (int nThisCoastPoint = 1; nThisCoastPoint < (nCoastSize - 1); nThisCoastPoint++)
47 {
48 // Calculate the signed curvature based on this point, and the points before and after
49 double const dCurvature = dCalcCurvature(nHandedness, m_VCoast[nCoast].pPtGetCoastlinePointExtCRS(nThisCoastPoint - 1), m_VCoast[nCoast].pPtGetCoastlinePointExtCRS(nThisCoastPoint), m_VCoast[nCoast].pPtGetCoastlinePointExtCRS(nThisCoastPoint + 1));
50
51 // Set the detailed curvature
52 m_VCoast[nCoast].SetDetailedCurvature(nThisCoastPoint, dCurvature);
53 }
54
55 // Set the curvature for the first and last coastline points
56 double dTemp = m_VCoast[nCoast].dGetDetailedCurvature(1);
57 m_VCoast[nCoast].SetDetailedCurvature(0, dTemp);
58
59 dTemp = m_VCoast[nCoast].dGetDetailedCurvature(nCoastSize - 2);
60 m_VCoast[nCoast].SetDetailedCurvature(nCoastSize - 1, dTemp);
61
62 // Now create the smoothed curvature
63 int const nHalfWindow = m_nCoastCurvatureMovingWindowSize / 2;
64
65 // Apply a running mean smoothing filter, with a variable window size at both ends of the coastline
66 for (int i = 0; i < nCoastSize; i++)
67 {
68 int nTmpWindow = 0;
69 double dWindowTot = 0;
70
71 for (int j = -nHalfWindow; j < m_nCoastCurvatureMovingWindowSize - nHalfWindow; j++)
72 {
73 // For points at both ends of the coastline, use a smaller window
74 int const k = i + j;
75
76 if ((k < 0) || (k >= nCoastSize))
77 continue;
78
79 dWindowTot += m_VCoast[nCoast].dGetDetailedCurvature(k);
80 nTmpWindow++;
81 }
82
83 m_VCoast[nCoast].SetSmoothCurvature(i, dWindowTot / static_cast<double>(nTmpWindow));
84 }
85
86 // Now calculate the mean and standard deviation of each set of curvature values
87 vector<double>* pVDetailed = m_VCoast[nCoast].pVGetDetailedCurvature();
88
89 double dSum = accumulate(pVDetailed->begin(), pVDetailed->end(), 0.0);
90 double dMean = dSum / static_cast<double>(pVDetailed->size());
91
92 m_VCoast[nCoast].SetDetailedCurvatureMean(dMean);
93
94 double dSquareSum = inner_product(pVDetailed->begin(), pVDetailed->end(), pVDetailed->begin(), 0.0);
95 double dSTD = sqrt(dSquareSum / static_cast<double>(pVDetailed->size()) - dMean * dMean);
96
97 m_VCoast[nCoast].SetDetailedCurvatureSTD(dSTD);
98
99 vector<double>* pVSmooth = m_VCoast[nCoast].pVGetSmoothCurvature();
100 dSum = accumulate(pVSmooth->begin(), pVSmooth->end(), 0.0),
101 dMean = dSum / static_cast<double>(pVSmooth->size());
102
103 m_VCoast[nCoast].SetSmoothCurvatureMean(dMean);
104
105 dSquareSum = inner_product(pVSmooth->begin(), pVSmooth->end(), pVSmooth->begin(), 0.0), dSTD = sqrt(dSquareSum / static_cast<double>(pVSmooth->size()) - dMean * dMean);
106 m_VCoast[nCoast].SetSmoothCurvatureSTD(dSTD);
107
108 double dMaxConvexDetailed = DBL_MAX;
109 double dMaxConvexSmoothed = DBL_MAX;
110
111 for (int mm = 0; mm < nCoastSize; mm++)
112 {
113 if (m_VCoast[nCoast].dGetDetailedCurvature(mm) < dMaxConvexDetailed)
114 {
115 dMaxConvexDetailed = m_VCoast[nCoast].dGetDetailedCurvature(mm);
116 }
117
118 if (m_VCoast[nCoast].dGetSmoothCurvature(mm) < dMaxConvexSmoothed)
119 {
120 dMaxConvexSmoothed = m_VCoast[nCoast].dGetSmoothCurvature(mm);
121 // nMaxConvexSmoothedCoastPoint = mm;
122 }
123
124 // Also set the pointer to a coastline-normal profile to null
125 }
126
127 if (bFPIsEqual(dMaxConvexDetailed, 0.0, TOLERANCE))
128 {
129 // We have a straight-line coast, so set the point of maximum convexity at the coast mid-point
130 int const nMaxConvexCoastPoint = nCoastSize / 2;
131
132 m_VCoast[nCoast].SetDetailedCurvature(nMaxConvexCoastPoint, STRAIGHT_COAST_MAX_DETAILED_CURVATURE);
133 m_VCoast[nCoast].SetSmoothCurvature(nMaxConvexCoastPoint, STRAIGHT_COAST_MAX_SMOOTH_CURVATURE);
134 }
135
136 // LogStream << "-----------------" << endl;
137 // for (int kk = 0; kk < m_VCoast.back().nGetCoastlineSize(); kk++)
138 // LogStream << kk << " [" << m_VCoast.back().pPtiGetCellMarkedAsCoastline(kk)->nGetX() << "][" << m_VCoast.back().pPtiGetCellMarkedAsCoastline(kk)->nGetY() << "] = {" << dGridCentroidXToExtCRSX(m_VCoast.back().pPtiGetCellMarkedAsCoastline(kk)->nGetX()) << ", " << dGridCentroidYToExtCRSY(m_VCoast.back().pPtiGetCellMarkedAsCoastline(kk)->nGetY()) << "}" << endl;
139 // LogStream << "-----------------" << endl;
140
141 // CGeom2DIPoint PtiMax = *m_VCoast[nCoast].pPtiGetCellMarkedAsCoastline(nMaxConvexDetailedCoastPoint);
142
143 // if (m_nLogFileDetail >= LOG_FILE_ALL)
144 // LogStream << m_ulIter << ": Max detailed convexity (" << m_VCoast[nCoast].dGetDetailedCurvature(nMaxConvexDetailedCoastPoint) << ") at raster coastline point " << nMaxConvexDetailedCoastPoint << " [" << PtiMax.nGetX() << "][" << PtiMax.nGetY() << "] = {" << dGridCentroidXToExtCRSX(PtiMax.nGetX()) << ", " << dGridCentroidYToExtCRSY(PtiMax.nGetY()) << "}" << endl;
145
146 // CGeom2DIPoint PtiMaxSmooth = *m_VCoast[nCoast].pPtiGetCellMarkedAsCoastline(nMaxConvexSmoothedCoastPoint);
147 // CGeom2DPoint PtMaxSmooth = *m_VCoast[nCoast].pPtGetCoastlinePointExtCRS(nMaxConvexSmoothedCoastPoint);
148
149 // if (m_nLogFileDetail >= LOG_FILE_ALL)
150 // LogStream << m_ulIter << ": Max smoothed convexity (" << m_VCoast[nCoast].dGetSmoothCurvature(nMaxConvexSmoothedCoastPoint) << ") near vector coastline point " << nMaxConvexSmoothedCoastPoint << ", at [" << PtiMaxSmooth.nGetX() << "][" << PtiMaxSmooth.nGetY() << "] = {" << PtMaxSmooth.dGetX() << ", " << PtMaxSmooth.dGetY() << "}" << endl;
151}
152
153//===============================================================================================================================
155//===============================================================================================================================
156double CSimulation::dCalcCurvature(int const nHandedness, CGeom2DPoint const* pPtBefore, CGeom2DPoint const* pPtThis, CGeom2DPoint const* pPtAfter)
157{
158 double const dAreax4 = 2 * dTriangleAreax2(pPtBefore, pPtThis, pPtAfter);
159 double dDist1 = dGetDistanceBetween(pPtBefore, pPtThis);
160 double dDist2 = dGetDistanceBetween(pPtThis, pPtAfter);
161 double dDist3 = dGetDistanceBetween(pPtBefore, pPtAfter);
162
163 // Safety checks
164 if (bFPIsEqual(dDist1, 0.0, TOLERANCE))
165 dDist1 = TOLERANCE;
166
167 if (bFPIsEqual(dDist2, 0.0, TOLERANCE))
168 dDist2 = TOLERANCE;
169
170 if (bFPIsEqual(dDist3, 0.0, TOLERANCE))
171 dDist3 = TOLERANCE;
172
173 double const dCurvature = dAreax4 / (dDist1 * dDist2 * dDist3);
174
175 // Reverse if left-handed
176 int const nShape = (nHandedness == LEFT_HANDED ? 1 : -1);
177
178 return (dCurvature * nShape * 1000);
179}
Contains CGeom2DPoint definitions.
Geometry class used to represent 2D point objects with floating-point coordinates.
Definition 2d_point.h:27
vector< CRWCoast > m_VCoast
The coastline objects.
static double dGetDistanceBetween(CGeom2DPoint const *, CGeom2DPoint const *)
Returns the distance (in external CRS) between two points.
int m_nCoastCurvatureMovingWindowSize
WHAT IS THOS FOR?
Definition simulation.h:583
static double dTriangleAreax2(CGeom2DPoint const *, CGeom2DPoint const *, CGeom2DPoint const *)
Returns twice the signed area of a triangle.
static double dCalcCurvature(int const, CGeom2DPoint const *, CGeom2DPoint const *, CGeom2DPoint const *)
Calculates signed Menger curvature (https://en.wikipedia.org/wiki/Menger_curvature#Definition) from t...
void DoCoastCurvature(int const, int const)
Calculates both detailed and smoothed curvature for every point on a coastline.
This file contains global definitions for CoastalME.
double const TOLERANCE
Definition cme.h:823
bool bFPIsEqual(const T d1, const T d2, const T dEpsilon)
Definition cme.h:1303
double const STRAIGHT_COAST_MAX_DETAILED_CURVATURE
Definition cme.h:827
double const STRAIGHT_COAST_MAX_SMOOTH_CURVATURE
Definition cme.h:828
int const LEFT_HANDED
Definition cme.h:512
Contains CRWCoast definitions.
Contains CSimulation definitions.