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 <iostream>
27using std::endl;
28
29#include <cmath>
30using std::sqrt;
31
32#include <numeric>
33using std::accumulate;
34using std::inner_product;
35
36#include "cme.h"
37#include "simulation.h"
38#include "coast.h"
39
40//===============================================================================================================================
42//===============================================================================================================================
43void CSimulation::DoCoastCurvature(int const nCoast, int const nHandedness)
44{
45 int nCoastSize = m_VCoast[nCoast].nGetCoastlineSize();
46
47 // Start with detailed curvature, do every point on the coastline, apart from the first and last points
48 for (int nThisCoastPoint = 1; nThisCoastPoint < (nCoastSize - 1); nThisCoastPoint++)
49 {
50 // Calculate the signed curvature based on this point, and the points before and after
51 double dCurvature = dCalcCurvature(nHandedness, m_VCoast[nCoast].pPtGetCoastlinePointExtCRS(nThisCoastPoint - 1), m_VCoast[nCoast].pPtGetCoastlinePointExtCRS(nThisCoastPoint), m_VCoast[nCoast].pPtGetCoastlinePointExtCRS(nThisCoastPoint + 1));
52
53 // Set the detailed curvature
54 m_VCoast[nCoast].SetDetailedCurvature(nThisCoastPoint, dCurvature);
55 }
56
57 // Set the curvature for the first and last coastline points
58 double dTemp = m_VCoast[nCoast].dGetDetailedCurvature(1);
59 m_VCoast[nCoast].SetDetailedCurvature(0, dTemp);
60
61 dTemp = m_VCoast[nCoast].dGetDetailedCurvature(nCoastSize - 2);
62 m_VCoast[nCoast].SetDetailedCurvature(nCoastSize - 1, dTemp);
63
64 // Now create the smoothed curvature
65 int const nHalfWindow = m_nCoastCurvatureMovingWindowSize / 2;
66
67 // Apply a running mean smoothing filter, with a variable window size at both ends of the coastline
68 for (int i = 0; i < nCoastSize; i++)
69 {
70 int nTmpWindow = 0;
71 double dWindowTot = 0;
72
73 for (int j = -nHalfWindow; j < m_nCoastCurvatureMovingWindowSize - nHalfWindow; j++)
74 {
75 // For points at both ends of the coastline, use a smaller window
76 int const k = i + j;
77
78 if ((k < 0) || (k >= nCoastSize))
79 continue;
80
81 dWindowTot += m_VCoast[nCoast].dGetDetailedCurvature(k);
82 nTmpWindow++;
83 }
84
85 m_VCoast[nCoast].SetSmoothCurvature(i, dWindowTot / static_cast<double>(nTmpWindow));
86 }
87
88 // Now calculate the mean and standard deviation of each set of curvature values
89 vector<double> *pVDetailed = m_VCoast[nCoast].pVGetDetailedCurvature();
90
91 double dSum = accumulate(pVDetailed->begin(), pVDetailed->end(), 0.0);
92 double dMean = dSum / static_cast<double>(pVDetailed->size());
93
94 m_VCoast[nCoast].SetDetailedCurvatureMean(dMean);
95
96 double dSquareSum = inner_product(pVDetailed->begin(), pVDetailed->end(), pVDetailed->begin(), 0.0);
97 double dSTD = sqrt(dSquareSum / static_cast<double>(pVDetailed->size()) - dMean * dMean);
98
99 m_VCoast[nCoast].SetDetailedCurvatureSTD(dSTD);
100
101 vector<double> *pVSmooth = m_VCoast[nCoast].pVGetSmoothCurvature();
102 dSum = accumulate(pVSmooth->begin(), pVSmooth->end(), 0.0),
103 dMean = dSum / static_cast<double>(pVSmooth->size());
104
105 m_VCoast[nCoast].SetSmoothCurvatureMean(dMean);
106
107 dSquareSum = inner_product(pVSmooth->begin(), pVSmooth->end(), pVSmooth->begin(), 0.0), dSTD = sqrt(dSquareSum / static_cast<double>(pVSmooth->size()) - dMean * dMean);
108 m_VCoast[nCoast].SetSmoothCurvatureSTD(dSTD);
109
110 double dMaxConvexDetailed = DBL_MAX;
111 double dMaxConvexSmoothed = DBL_MAX;
112
113 for (int mm = 0; mm < nCoastSize; mm++)
114 {
115 if (m_VCoast[nCoast].dGetDetailedCurvature(mm) < dMaxConvexDetailed)
116 {
117 dMaxConvexDetailed = m_VCoast[nCoast].dGetDetailedCurvature(mm);
118 }
119
120 if (m_VCoast[nCoast].dGetSmoothCurvature(mm) < dMaxConvexSmoothed)
121 {
122 dMaxConvexSmoothed = m_VCoast[nCoast].dGetSmoothCurvature(mm);
123 // nMaxConvexSmoothedCoastPoint = mm;
124 }
125
126 // Also set the pointer to a coastline-normal profile to null
127
128 }
129
130 if (bFPIsEqual(dMaxConvexDetailed, 0.0, TOLERANCE))
131 {
132 // We have a straight-line coast, so set the point of maximum convexity at the coast mid-point
133 int nMaxConvexCoastPoint = nCoastSize / 2;
134
135 m_VCoast[nCoast].SetDetailedCurvature(nMaxConvexCoastPoint, STRAIGHT_COAST_MAX_DETAILED_CURVATURE);
136 m_VCoast[nCoast].SetSmoothCurvature(nMaxConvexCoastPoint, STRAIGHT_COAST_MAX_SMOOTH_CURVATURE);
137 }
138
139// LogStream << "-----------------" << endl;
140// for (int kk = 0; kk < m_VCoast.back().nGetCoastlineSize(); kk++)
141// 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;
142// LogStream << "-----------------" << endl;
143
144 // CGeom2DIPoint PtiMax = *m_VCoast[nCoast].pPtiGetCellMarkedAsCoastline(nMaxConvexDetailedCoastPoint);
145
146 // if (m_nLogFileDetail >= LOG_FILE_ALL)
147 // 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;
148
149 // CGeom2DIPoint PtiMaxSmooth = *m_VCoast[nCoast].pPtiGetCellMarkedAsCoastline(nMaxConvexSmoothedCoastPoint);
150 // CGeom2DPoint PtMaxSmooth = *m_VCoast[nCoast].pPtGetCoastlinePointExtCRS(nMaxConvexSmoothedCoastPoint);
151
152 // if (m_nLogFileDetail >= LOG_FILE_ALL)
153 // 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;
154}
155
156//===============================================================================================================================
158//===============================================================================================================================
159double CSimulation::dCalcCurvature(int const nHandedness, CGeom2DPoint const* pPtBefore, CGeom2DPoint const* pPtThis, CGeom2DPoint const* pPtAfter)
160{
161 double dAreax4 = 2 * dTriangleAreax2(pPtBefore, pPtThis, pPtAfter);
162 double dDist1 = dGetDistanceBetween(pPtBefore, pPtThis);
163 double dDist2 = dGetDistanceBetween(pPtThis, pPtAfter);
164 double dDist3 = dGetDistanceBetween(pPtBefore, pPtAfter);
165
166 // Safety checks
167 if (bFPIsEqual(dDist1, 0.0, TOLERANCE))
168 dDist1 = TOLERANCE;
169
170 if (bFPIsEqual(dDist2, 0.0, TOLERANCE))
171 dDist2 = TOLERANCE;
172
173 if (bFPIsEqual(dDist3, 0.0, TOLERANCE))
174 dDist3 = TOLERANCE;
175
176 double dCurvature = dAreax4 / (dDist1 * dDist2 * dDist3);
177
178 // Reverse if left-handed
179 int nShape = (nHandedness == LEFT_HANDED ? 1 : -1);
180
181 return (dCurvature * nShape * 1000);
182}
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
Definition simulation.h:599
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:811
bool bFPIsEqual(const T d1, const T d2, const T dEpsilon)
Definition cme.h:1284
double const STRAIGHT_COAST_MAX_DETAILED_CURVATURE
Definition cme.h:815
double const STRAIGHT_COAST_MAX_SMOOTH_CURVATURE
Definition cme.h:816
int const LEFT_HANDED
Definition cme.h:510
Contains CRWCoast definitions.
Contains CSimulation definitions.