mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#3505 First go at contour lines
This commit is contained in:
parent
1227eff8bf
commit
69d079f942
@ -40,6 +40,25 @@ void Riv2dGridProjectionPartMgr::appendProjectionToModel(cvf::ModelBasicList* mo
|
||||
|
||||
model->addPart(part.p());
|
||||
}
|
||||
|
||||
std::vector<cvf::ref<cvf::DrawableGeo>> contourDrawables = createContourPolygons(displayCoordTransform);
|
||||
for (cvf::ref<cvf::DrawableGeo> contourDrawable : contourDrawables)
|
||||
{
|
||||
if (contourDrawable.notNull() && contourDrawable->boundingBox().isValid())
|
||||
{
|
||||
caf::MeshEffectGenerator meshEffectGen(cvf::Color3::BLACK);
|
||||
meshEffectGen.setLineWidth(1.0f);
|
||||
meshEffectGen.createAndConfigurePolygonOffsetRenderState(caf::PO_2);
|
||||
cvf::ref<cvf::Effect> effect = meshEffectGen.generateCachedEffect();
|
||||
|
||||
cvf::ref<cvf::Part> part = new cvf::Part;
|
||||
part->setDrawable(contourDrawable.p());
|
||||
part->setEffect(effect.p());
|
||||
part->setSourceInfo(new RivMeshLinesSourceInfo(m_2dGridProjection.p()));
|
||||
|
||||
model->addPart(part.p());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -120,3 +139,35 @@ cvf::ref<cvf::DrawableGeo> Riv2dGridProjectionPartMgr::createDrawable(const caf:
|
||||
geo->setVertexArray(vertexArray.p());
|
||||
return geo;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<cvf::ref<cvf::DrawableGeo>> Riv2dGridProjectionPartMgr::createContourPolygons(const caf::DisplayCoordTransform* displayCoordTransform) const
|
||||
{
|
||||
Rim2dGridProjection::ContourPolygons contourPolygons = m_2dGridProjection->generateContourPolygons(displayCoordTransform);
|
||||
|
||||
std::vector<cvf::ref<cvf::DrawableGeo>> contourDrawables;
|
||||
contourDrawables.reserve(contourPolygons.size());
|
||||
for (size_t i = 0; i < contourPolygons.size(); ++i)
|
||||
{
|
||||
cvf::ref<cvf::Vec3fArray> vertexArray = contourPolygons[i];
|
||||
std::vector<cvf::uint> indices;
|
||||
indices.reserve(contourPolygons[i]->size());
|
||||
for (cvf::uint j = 0; j < contourPolygons[i]->size(); ++j)
|
||||
{
|
||||
indices.push_back(j);
|
||||
}
|
||||
|
||||
cvf::ref<cvf::PrimitiveSetIndexedUInt> indexedUInt = new cvf::PrimitiveSetIndexedUInt(cvf::PrimitiveType::PT_LINES);
|
||||
cvf::ref<cvf::UIntArray> indexArray = new cvf::UIntArray(indices);
|
||||
indexedUInt->setIndices(indexArray.p());
|
||||
|
||||
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
|
||||
|
||||
geo->addPrimitiveSet(indexedUInt.p());
|
||||
geo->setVertexArray(vertexArray.p());
|
||||
contourDrawables.push_back(geo);
|
||||
}
|
||||
return contourDrawables;
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ public:
|
||||
void removeTrianglesWithNoResult(cvf::UIntArray* uintArray) const;
|
||||
private:
|
||||
cvf::ref<cvf::DrawableGeo> createDrawable(const caf::DisplayCoordTransform* displayCoordTransform) const;
|
||||
std::vector<cvf::ref<cvf::DrawableGeo>> createContourPolygons(const caf::DisplayCoordTransform* displayCoordTransform) const;
|
||||
private:
|
||||
caf::PdmPointer<Rim2dGridProjection> m_2dGridProjection;
|
||||
};
|
||||
|
@ -11,16 +11,20 @@
|
||||
|
||||
#include "RivReservoirViewPartMgr.h"
|
||||
|
||||
#include "RimCellRangeFilterCollection.h"
|
||||
#include "RimEclipseCellColors.h"
|
||||
#include "RimEclipseView.h"
|
||||
#include "RimEclipseResultCase.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimCellRangeFilterCollection.h"
|
||||
#include "RimRegularLegendConfig.h"
|
||||
|
||||
#include "cafContourLines.h"
|
||||
#include "cafPdmUiDoubleSliderEditor.h"
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
|
||||
#include "cvfArray.h"
|
||||
#include "cvfCellRange.h"
|
||||
#include "cvfScalarMapper.h"
|
||||
#include "cvfStructGridGeometryGenerator.h"
|
||||
|
||||
#include <QDebug>
|
||||
@ -127,6 +131,41 @@ void Rim2dGridProjection::generateVertices(cvf::Vec3fArray* vertices, const caf:
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
Rim2dGridProjection::ContourPolygons Rim2dGridProjection::generateContourPolygons(const caf::DisplayCoordTransform* displayCoordTransform)
|
||||
{
|
||||
std::vector<cvf::ref<cvf::Vec3fArray>> contourPolygons;
|
||||
|
||||
cvf::BoundingBox boundingBox = eclipseCase()->activeCellsBoundingBox();
|
||||
|
||||
std::vector<double> contourLevels;
|
||||
m_legendConfig->scalarMapper()->majorTickValues(&contourLevels);
|
||||
int nContourLevels = static_cast<int>(contourLevels.size());
|
||||
if (nContourLevels > 2)
|
||||
{
|
||||
contourLevels[0] += (contourLevels[1] - contourLevels[0]) * 0.01;
|
||||
contourLevels[nContourLevels - 1] -= (contourLevels[nContourLevels - 1] - contourLevels[nContourLevels - 2]) * 0.01;
|
||||
std::vector<std::vector<cvf::Vec2d>> contourLines;
|
||||
caf::ContourLines::create(m_aggregatedResults, xPositions(), yPositions(), contourLevels, &contourLines);
|
||||
|
||||
contourPolygons.reserve(contourLines.size());
|
||||
for (size_t i = 0; i < contourLines.size(); ++i)
|
||||
{
|
||||
cvf::ref<cvf::Vec3fArray> contourPolygon = new cvf::Vec3fArray(contourLines[i].size());
|
||||
for (size_t j = 0; j < contourLines[i].size(); ++j)
|
||||
{
|
||||
cvf::Vec3d contourPoint3d = cvf::Vec3d(contourLines[i][j], boundingBox.min().z());
|
||||
cvf::Vec3d displayPoint3d = displayCoordTransform->transformToDisplayCoord(contourPoint3d);
|
||||
(*contourPolygon)[j] = cvf::Vec3f(displayPoint3d);
|
||||
}
|
||||
contourPolygons.push_back(contourPolygon);
|
||||
}
|
||||
}
|
||||
return contourPolygons;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -215,6 +254,14 @@ void Rim2dGridProjection::updateDefaultSampleSpacingFromGrid()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<double>& Rim2dGridProjection::aggregatedResults() const
|
||||
{
|
||||
return m_aggregatedResults;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -487,6 +534,47 @@ void Rim2dGridProjection::updateLegend()
|
||||
m_legendConfig->setTitle(QString("2d Projection:\n%1").arg(cellColors->resultVariableUiShortName()));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> Rim2dGridProjection::xPositions() const
|
||||
{
|
||||
cvf::BoundingBox boundingBox = eclipseCase()->activeCellsBoundingBox();
|
||||
cvf::Vec3d gridExtent = boundingBox.extent();
|
||||
double origin = boundingBox.min().x();
|
||||
|
||||
cvf::Vec2ui gridSize2d = surfaceGridSize();
|
||||
|
||||
std::vector<double> positions;
|
||||
positions.reserve(gridSize2d.x());
|
||||
for (uint i = 0; i < gridSize2d.x(); ++i)
|
||||
{
|
||||
positions.push_back(origin + (i * gridExtent.x()) / (gridSize2d.x() - 1));
|
||||
}
|
||||
|
||||
return positions;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> Rim2dGridProjection::yPositions() const
|
||||
{
|
||||
cvf::BoundingBox boundingBox = eclipseCase()->activeCellsBoundingBox();
|
||||
cvf::Vec3d gridExtent = boundingBox.extent();
|
||||
double origin = boundingBox.min().y();
|
||||
cvf::Vec2ui gridSize2d = surfaceGridSize();
|
||||
|
||||
std::vector<double> positions;
|
||||
positions.reserve(gridSize2d.y());
|
||||
for (uint j = 0; j < gridSize2d.y(); ++j)
|
||||
{
|
||||
positions.push_back(origin + (j * gridExtent.y()) / (gridSize2d.y() - 1));
|
||||
}
|
||||
|
||||
return positions;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -49,16 +49,20 @@ public:
|
||||
RESULTS_MAX_VALUE
|
||||
};
|
||||
typedef caf::AppEnum<ResultAggregationEnum> ResultAggregation;
|
||||
typedef std::vector<cvf::ref<cvf::Vec3fArray>> ContourPolygons;
|
||||
|
||||
Rim2dGridProjection();
|
||||
~Rim2dGridProjection() override;
|
||||
|
||||
void generateVertices(cvf::Vec3fArray* vertices, const caf::DisplayCoordTransform* displayCoordTransform);
|
||||
|
||||
ContourPolygons generateContourPolygons(const caf::DisplayCoordTransform* displayCoordTransform);
|
||||
void generateResults();
|
||||
double maxValue() const;
|
||||
double minValue() const;
|
||||
double sampleSpacing() const;
|
||||
void updateDefaultSampleSpacingFromGrid();
|
||||
const std::vector<double>& aggregatedResults() const;
|
||||
|
||||
double value(uint i, uint j) const;
|
||||
bool hasResultAt(uint i, uint j) const;
|
||||
@ -72,12 +76,15 @@ public:
|
||||
void updateLegend();
|
||||
|
||||
protected:
|
||||
void generateGridMapping();
|
||||
void calculateCellRangeVisibility();
|
||||
void calculatePropertyFilterVisibility();
|
||||
cvf::Vec2d globalPos2d(uint i, uint j) const;
|
||||
const std::vector<std::pair<size_t, float>>& cellsAtPos2d(uint i, uint j) const;
|
||||
std::vector<std::pair<size_t, float>> visibleCellsAndWeightMatching2dPoint(const cvf::Vec2d& globalPos2d) const;
|
||||
void generateGridMapping();
|
||||
void calculateCellRangeVisibility();
|
||||
void calculatePropertyFilterVisibility();
|
||||
cvf::Vec2d globalPos2d(uint i, uint j) const;
|
||||
const std::vector<std::pair<size_t, float>>& cellsAtPos2d(uint i, uint j) const;
|
||||
std::vector<double> xPositions() const;
|
||||
std::vector<double> yPositions() const;
|
||||
|
||||
std::vector<std::pair<size_t, float>> visibleCellsAndWeightMatching2dPoint(const cvf::Vec2d& globalPos2d) const;
|
||||
|
||||
const RimEclipseResultCase* eclipseCase() const;
|
||||
RigMainGrid* mainGrid() const;
|
||||
|
@ -35,6 +35,8 @@ add_library( ${PROJECT_NAME}
|
||||
cvfCellRange.h
|
||||
cafColorTable.cpp
|
||||
cafColorTable.h
|
||||
cafContourLines.cpp
|
||||
cafContourLines.h
|
||||
|
||||
cvfStructGridGeometryGenerator.cpp
|
||||
cvfStructGridGeometryGenerator.h
|
||||
|
270
Fwk/AppFwk/CommonCode/cafContourLines.cpp
Normal file
270
Fwk/AppFwk/CommonCode/cafContourLines.cpp
Normal file
@ -0,0 +1,270 @@
|
||||
#include "cafContourLines.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
//===========================================================================
|
||||
// Note that castab is arranged differently from the FORTRAN code because
|
||||
// Fortran and C/C++ arrays are transposed of each other, in this case
|
||||
// it is more tricky as castab is in 3 dimension
|
||||
//===========================================================================
|
||||
const int caf::ContourLines::s_castab[3][3][3] =
|
||||
{
|
||||
{
|
||||
{ 0,0,8 },{ 0,2,5 },{ 7,6,9 }
|
||||
},
|
||||
{
|
||||
{ 0,3,4 },{ 1,3,1 },{ 4,3,0 }
|
||||
},
|
||||
{
|
||||
{ 9,6,7 },{ 5,2,0 },{ 8,0,0 }
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void caf::ContourLines::create(const std::vector<double>& dataXY, const std::vector<double>& xCoords, const std::vector<double>& yCoords, const std::vector<double>& contourLevels, std::vector<std::vector<cvf::Vec2d>>* polygons)
|
||||
{
|
||||
CVF_ASSERT(!contourLevels.empty());
|
||||
int nContourLevels = static_cast<int>(contourLevels.size());
|
||||
std::vector<int> sh(5, 0);
|
||||
std::vector<double> h(5, 0.0), xh(5, 0.0), yh(5, 0.0);
|
||||
|
||||
int nx = static_cast<int>(xCoords.size());
|
||||
int ny = static_cast<int>(yCoords.size());
|
||||
|
||||
CVF_ASSERT(static_cast<int>(dataXY.size()) == nx * ny);
|
||||
|
||||
polygons->resize(nContourLevels);
|
||||
|
||||
//===========================================================================
|
||||
// The indexing of im and jm should be noted as it has to start from zero
|
||||
// unlike the fortran counter part
|
||||
//===========================================================================
|
||||
int im[4] = { 0,1,1,0 }, jm[4] = { 0,0,1,1 };
|
||||
|
||||
for (int j = (ny - 2); j >= 0; j--) {
|
||||
for (int i = 0; i < nx - 1; i++) {
|
||||
double temp1, temp2;
|
||||
temp1 = std::min(saneValue(gridIndex1d(i, j, nx), dataXY, contourLevels),
|
||||
saneValue(gridIndex1d(i, j + 1, nx), dataXY, contourLevels));
|
||||
temp2 = std::min(saneValue(gridIndex1d(i + 1, j, nx), dataXY, contourLevels),
|
||||
saneValue(gridIndex1d(i + 1, j + 1, nx), dataXY, contourLevels));
|
||||
double dmin = std::min(temp1, temp2);
|
||||
temp1 = std::max(saneValue(gridIndex1d(i, j, nx), dataXY, contourLevels),
|
||||
saneValue(gridIndex1d(i, j + 1, nx), dataXY, contourLevels));
|
||||
temp2 = std::max(saneValue(gridIndex1d(i + 1, j, nx), dataXY, contourLevels),
|
||||
saneValue(gridIndex1d(i + 1, j + 1, nx), dataXY, contourLevels));
|
||||
double dmax = std::max(temp1, temp2);
|
||||
if (dmax > contourLevels[0] && dmin < contourLevels[nContourLevels - 1]) {
|
||||
for (int k = 0; k < nContourLevels; k++) {
|
||||
if (contourLevels[k] >= dmin && contourLevels[k] <= dmax) {
|
||||
for (int m = 4; m >= 0; m--) {
|
||||
if (m > 0) {
|
||||
//=============================================================
|
||||
// The indexing of im and jm should be noted as it has to
|
||||
// start from zero
|
||||
//=============================================================
|
||||
h[m] = saneValue(gridIndex1d(i + im[m - 1], j + jm[m - 1], nx), dataXY, contourLevels) - contourLevels[k];
|
||||
xh[m] = xCoords[i + im[m - 1]];
|
||||
yh[m] = yCoords[j + jm[m - 1]];
|
||||
}
|
||||
else {
|
||||
h[0] = 0.25*(h[1] + h[2] + h[3] + h[4]);
|
||||
xh[0] = 0.5*(xCoords[i] + xCoords[i + 1]);
|
||||
yh[0] = 0.5*(yCoords[j] + yCoords[j + 1]);
|
||||
}
|
||||
if (h[m] > 0.0) {
|
||||
sh[m] = 1;
|
||||
}
|
||||
else if (h[m] < 0.0) {
|
||||
sh[m] = -1;
|
||||
}
|
||||
else
|
||||
sh[m] = 0;
|
||||
}
|
||||
//=================================================================
|
||||
//
|
||||
// Note: at this stage the relative heights of the corners and the
|
||||
// centre are in the h array, and the corresponding coordinates are
|
||||
// in the xh and yh arrays. The centre of the box is indexed by 0
|
||||
// and the 4 corners by 1 to 4 as shown below.
|
||||
// Each triangle is then indexed by the parameter m, and the 3
|
||||
// vertices of each triangle are indexed by parameters m1,m2,and
|
||||
// m3.
|
||||
// It is assumed that the centre of the box is always vertex 2
|
||||
// though this isimportant only when all 3 vertices lie exactly on
|
||||
// the same contour level, in which case only the side of the box
|
||||
// is drawn.
|
||||
//
|
||||
//
|
||||
// vertex 4 +-------------------+ vertex 3
|
||||
// | \ / |
|
||||
// | \ m-3 / |
|
||||
// | \ / |
|
||||
// | \ / |
|
||||
// | m=2 X m=2 | the centre is vertex 0
|
||||
// | / \ |
|
||||
// | / \ |
|
||||
// | / m=1 \ |
|
||||
// | / \ |
|
||||
// vertex 1 +-------------------+ vertex 2
|
||||
//
|
||||
//
|
||||
//
|
||||
// Scan each triangle in the box
|
||||
//
|
||||
//=================================================================
|
||||
for (int m = 1; m <= 4; m++) {
|
||||
int m1 = m;
|
||||
int m2 = 0;
|
||||
int m3 = 0;
|
||||
if (m != 4)
|
||||
m3 = m + 1;
|
||||
else
|
||||
m3 = 1;
|
||||
int case_value = s_castab[sh[m1] + 1][sh[m2] + 1][sh[m3] + 1];
|
||||
|
||||
double x1 = 0.0, x2 = 0.0, y1 = 0.0, y2 = 0.0;
|
||||
|
||||
if (case_value != 0) {
|
||||
switch (case_value) {
|
||||
//===========================================================
|
||||
// Case 1 - Line between vertices 1 and 2
|
||||
//===========================================================
|
||||
case 1:
|
||||
x1 = xh[m1];
|
||||
y1 = yh[m1];
|
||||
x2 = xh[m2];
|
||||
y2 = yh[m2];
|
||||
break;
|
||||
//===========================================================
|
||||
// Case 2 - Line between vertices 2 and 3
|
||||
//===========================================================
|
||||
case 2:
|
||||
x1 = xh[m2];
|
||||
y1 = yh[m2];
|
||||
x2 = xh[m3];
|
||||
y2 = yh[m3];
|
||||
break;
|
||||
//===========================================================
|
||||
// Case 3 - Line between vertices 3 and 1
|
||||
//===========================================================
|
||||
case 3:
|
||||
x1 = xh[m3];
|
||||
y1 = yh[m3];
|
||||
x2 = xh[m1];
|
||||
y2 = yh[m1];
|
||||
break;
|
||||
//===========================================================
|
||||
// Case 4 - Line between vertex 1 and side 2-3
|
||||
//===========================================================
|
||||
case 4:
|
||||
x1 = xh[m1];
|
||||
y1 = yh[m1];
|
||||
x2 = xsect(m2, m3, h, xh, yh);
|
||||
y2 = ysect(m2, m3, h, xh, yh);
|
||||
break;
|
||||
//===========================================================
|
||||
// Case 5 - Line between vertex 2 and side 3-1
|
||||
//===========================================================
|
||||
case 5:
|
||||
x1 = xh[m2];
|
||||
y1 = yh[m2];
|
||||
x2 = xsect(m3, m1, h, xh, yh);
|
||||
y2 = ysect(m3, m1, h, xh, yh);
|
||||
break;
|
||||
//===========================================================
|
||||
// Case 6 - Line between vertex 3 and side 1-2
|
||||
//===========================================================
|
||||
case 6:
|
||||
x1 = xh[m3];
|
||||
y1 = yh[m3];
|
||||
x2 = xsect(m1, m2, h, xh, yh);
|
||||
y2 = ysect(m1, m2, h, xh, yh);
|
||||
break;
|
||||
//===========================================================
|
||||
// Case 7 - Line between sides 1-2 and 2-3
|
||||
//===========================================================
|
||||
case 7:
|
||||
x1 = xsect(m1, m2, h, xh, yh);
|
||||
y1 = ysect(m1, m2, h, xh, yh);
|
||||
x2 = xsect(m2, m3, h, xh, yh);
|
||||
y2 = ysect(m2, m3, h, xh, yh);
|
||||
break;
|
||||
//===========================================================
|
||||
// Case 8 - Line between sides 2-3 and 3-1
|
||||
//===========================================================
|
||||
case 8:
|
||||
x1 = xsect(m2, m3, h, xh, yh);
|
||||
y1 = ysect(m2, m3, h, xh, yh);
|
||||
x2 = xsect(m3, m1, h, xh, yh);
|
||||
y2 = ysect(m3, m1, h, xh, yh);
|
||||
break;
|
||||
//===========================================================
|
||||
// Case 9 - Line between sides 3-1 and 1-2
|
||||
//===========================================================
|
||||
case 9:
|
||||
x1 = xsect(m3, m1, h, xh, yh);
|
||||
y1 = ysect(m3, m1, h, xh, yh);
|
||||
x2 = xsect(m1, m2, h, xh, yh);
|
||||
y2 = ysect(m1, m2, h, xh, yh);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//=============================================================
|
||||
// Put your processing code here and comment out the printf
|
||||
//=============================================================
|
||||
polygons->at(k).push_back(cvf::Vec2d(x1, y1));
|
||||
polygons->at(k).push_back(cvf::Vec2d(x2, y2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double caf::ContourLines::saneValue(int index, const std::vector<double>& dataXY, const std::vector<double>& contourLevels)
|
||||
{
|
||||
CVF_ASSERT(index >= 0 && index < static_cast<int>(dataXY.size()));
|
||||
double range = std::max(1.0, contourLevels.back() - contourLevels.front());
|
||||
// Place all invalid values below the bottom contour level.
|
||||
if (dataXY[index] == -std::numeric_limits<double>::infinity() ||
|
||||
dataXY[index] == std::numeric_limits<double>::infinity())
|
||||
{
|
||||
return contourLevels.front() - range;
|
||||
}
|
||||
return dataXY[index];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double caf::ContourLines::xsect(int p1, int p2, const std::vector<double>& h, const std::vector<double>& xh, const std::vector<double>& yh)
|
||||
{
|
||||
return (h[p2] * xh[p1] - h[p1] * xh[p2]) / (h[p2] - h[p1]);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double caf::ContourLines::ysect(int p1, int p2, const std::vector<double>& h, const std::vector<double>& xh, const std::vector<double>& yh)
|
||||
{
|
||||
return (h[p2] * yh[p1] - h[p1] * yh[p2]) / (h[p2] - h[p1]);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int caf::ContourLines::gridIndex1d(int i, int j, int nx)
|
||||
{
|
||||
return j * nx + i;
|
||||
}
|
53
Fwk/AppFwk/CommonCode/cafContourLines.h
Normal file
53
Fwk/AppFwk/CommonCode/cafContourLines.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright (c) 1996-1997 Nicholas Yue
|
||||
|
||||
This software is copyrighted by Nicholas Yue. This code is base on the work of
|
||||
Paul D. Bourke CONREC.F routine
|
||||
|
||||
The authors hereby grant permission to use, copy, and distribute this
|
||||
software and its documentation for any purpose, provided that existing
|
||||
copyright notices are retained in all copies and that this notice is included
|
||||
verbatim in any distributions. Additionally, the authors grant permission to
|
||||
modify this software and its documentation for any purpose, provided that
|
||||
such modifications are not distributed without the explicit consent of the
|
||||
authors and that existing copyright notices are retained in all copies. Some
|
||||
of the algorithms implemented by this software are patented, observe all
|
||||
applicable patent law.
|
||||
|
||||
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
|
||||
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
|
||||
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
|
||||
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
|
||||
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN
|
||||
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
|
||||
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfVector2.h"
|
||||
#include <vector>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
class ContourLines
|
||||
{
|
||||
public:
|
||||
static void create(const std::vector<double>& dataXY,
|
||||
const std::vector<double>& xPositions,
|
||||
const std::vector<double>& yPositions,
|
||||
const std::vector<double>& contourLevels,
|
||||
std::vector<std::vector<cvf::Vec2d>>* polygons);
|
||||
private:
|
||||
static double saneValue(int index, const std::vector<double>& dataXY, const std::vector<double>& contourLevels);
|
||||
static double xsect(int p1, int p2, const std::vector<double>& h, const std::vector<double>& xh, const std::vector<double>& yh);
|
||||
static double ysect(int p1, int p2, const std::vector<double>& h, const std::vector<double>& xh, const std::vector<double>& yh);
|
||||
static int gridIndex1d(int i, int j, int nx);
|
||||
private:
|
||||
static const int s_castab[3][3][3];
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user