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
15This file is part of CoastalME, the Coastal Modelling Environment.
16
17CoastalME 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
19This 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
21You 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 for (int j = -nHalfWindow; j < m_nCoastCurvatureMovingWindowSize - nHalfWindow; j++)
73 {
74 // For points at both ends of the coastline, use a smaller window
75 int const k = i+j;
76
77 if ((k < 0) || (k >= nCoastSize))
78 continue;
79
80 dWindowTot += m_VCoast[nCoast].dGetDetailedCurvature(k);
81 nTmpWindow++;
82 }
83
84 m_VCoast[nCoast].SetSmoothCurvature(i, dWindowTot / static_cast<double>(nTmpWindow));
85 }
86
87 // Now calculate the mean and standard deviation of each set of curvature values
88 vector<double>* pVDetailed = m_VCoast[nCoast].pVGetDetailedCurvature();
89
90 double dSum = accumulate(pVDetailed->begin(), pVDetailed->end(), 0.0);
91 double dMean = dSum / static_cast<double>(pVDetailed->size());
92
93 m_VCoast[nCoast].SetDetailedCurvatureMean(dMean);
94
95 double dSquareSum = inner_product(pVDetailed->begin(), pVDetailed->end(), pVDetailed->begin(), 0.0);
96 double dSTD = sqrt(dSquareSum / static_cast<double>(pVDetailed->size()) - dMean * dMean);
97
98 m_VCoast[nCoast].SetDetailedCurvatureSTD(dSTD);
99
100 vector<double>* pVSmooth = m_VCoast[nCoast].pVGetSmoothCurvature();
101 dSum = accumulate(pVSmooth->begin(), pVSmooth->end(), 0.0),
102 dMean = dSum / static_cast<double>(pVSmooth->size());
103
104 m_VCoast[nCoast].SetSmoothCurvatureMean(dMean);
105
106 dSquareSum = inner_product(pVSmooth->begin(), pVSmooth->end(), pVSmooth->begin(), 0.0), dSTD = sqrt(dSquareSum / static_cast<double>(pVSmooth->size()) - dMean * dMean);
107 m_VCoast[nCoast].SetSmoothCurvatureSTD(dSTD);
108
109 double dMaxConvexDetailed = DBL_MAX;
110 double dMaxConvexSmoothed = DBL_MAX;
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
128 if (bFPIsEqual(dMaxConvexDetailed, 0.0, TOLERANCE))
129 {
130 // We have a straight-line coast, so set the point of maximum convexity at the coast mid-point
131 int nMaxConvexCoastPoint = nCoastSize / 2;
132
133 m_VCoast[nCoast].SetDetailedCurvature(nMaxConvexCoastPoint, STRAIGHT_COAST_MAX_DETAILED_CURVATURE);
134 m_VCoast[nCoast].SetSmoothCurvature(nMaxConvexCoastPoint, STRAIGHT_COAST_MAX_SMOOTH_CURVATURE);
135 }
136
137// LogStream << "-----------------" << endl;
138// for (int kk = 0; kk < m_VCoast.back().nGetCoastlineSize(); kk++)
139// 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;
140// LogStream << "-----------------" << endl;
141
142 // CGeom2DIPoint PtiMax = *m_VCoast[nCoast].pPtiGetCellMarkedAsCoastline(nMaxConvexDetailedCoastPoint);
143
144 // if (m_nLogFileDetail >= LOG_FILE_ALL)
145 // 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;
146
147 // CGeom2DIPoint PtiMaxSmooth = *m_VCoast[nCoast].pPtiGetCellMarkedAsCoastline(nMaxConvexSmoothedCoastPoint);
148 // CGeom2DPoint PtMaxSmooth = *m_VCoast[nCoast].pPtGetCoastlinePointExtCRS(nMaxConvexSmoothedCoastPoint);
149
150 // if (m_nLogFileDetail >= LOG_FILE_ALL)
151 // 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;
152}
153
154//===============================================================================================================================
156//===============================================================================================================================
157double CSimulation::dCalcCurvature(int const nHandedness, CGeom2DPoint const* pPtBefore, CGeom2DPoint const* pPtThis, CGeom2DPoint const* pPtAfter)
158{
159 double dAreax4 = 2 * dTriangleAreax2(pPtBefore, pPtThis, pPtAfter);
160 double dDist1 = dGetDistanceBetween(pPtBefore, pPtThis);
161 double dDist2 = dGetDistanceBetween(pPtThis, pPtAfter);
162 double dDist3 = dGetDistanceBetween(pPtBefore, pPtAfter);
163
164 // Safety checks
165 if (bFPIsEqual(dDist1, 0.0, TOLERANCE))
166 dDist1 = TOLERANCE;
167
168 if (bFPIsEqual(dDist2, 0.0, TOLERANCE))
169 dDist2 = TOLERANCE;
170
171 if (bFPIsEqual(dDist3, 0.0, TOLERANCE))
172 dDist3 = TOLERANCE;
173
174 double dCurvature = dAreax4 / (dDist1 * dDist2 * dDist3);
175
176 // Reverse if left-handed
177 int nShape = (nHandedness == LEFT_HANDED ? 1 : -1);
178
179 return (dCurvature * nShape * 1000);
180}
181
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:538
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:698
bool bFPIsEqual(const T d1, const T d2, const T dEpsilon)
Definition cme.h:1176
double const STRAIGHT_COAST_MAX_DETAILED_CURVATURE
Definition cme.h:701
double const STRAIGHT_COAST_MAX_SMOOTH_CURVATURE
Definition cme.h:702
int const LEFT_HANDED
Definition cme.h:398
Contains CRWCoast definitions.
Contains CSimulation definitions.