mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#3970 Contour Maps: improve edge look
* Remove excess tiny triangles around edges * Remove labels from contour lines that overlap inner contour lines
This commit is contained in:
@@ -214,17 +214,16 @@ void caf::ContourLines::create(const std::vector<double>& dataXY, const std::vec
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<caf::ContourLines::ClosedPolygons> caf::ContourLines::create(const std::vector<double>& dataXY,
|
||||
const std::vector<double>& xPositions,
|
||||
const std::vector<double>& yPositions,
|
||||
const std::vector<double>& contourLevels,
|
||||
double areaThreshold)
|
||||
std::vector<caf::ContourLines::ListOfLineSegments> caf::ContourLines::create(const std::vector<double>& dataXY,
|
||||
const std::vector<double>& xPositions,
|
||||
const std::vector<double>& yPositions,
|
||||
const std::vector<double>& contourLevels)
|
||||
{
|
||||
const double eps = 1.0e-4;
|
||||
std::vector<std::vector<cvf::Vec2d>> contourLineSegments;
|
||||
caf::ContourLines::create(dataXY, xPositions, yPositions, contourLevels, &contourLineSegments);
|
||||
|
||||
std::vector<ClosedPolygons> closedPolygonsPerLevel(contourLevels.size());
|
||||
std::vector<ListOfLineSegments> listOfSegmentsPerLevel(contourLevels.size());
|
||||
|
||||
for (size_t i = 0; i < contourLevels.size(); ++i)
|
||||
{
|
||||
@@ -232,84 +231,16 @@ std::vector<caf::ContourLines::ClosedPolygons> caf::ContourLines::create(const s
|
||||
size_t nSegments = nPoints / 2;
|
||||
if (nSegments >= 3u) // Need at least three segments for a closed polygon
|
||||
{
|
||||
std::list<std::pair<cvf::Vec2d, cvf::Vec2d>> unorderedSegments;
|
||||
ListOfLineSegments unorderedSegments;
|
||||
for (size_t j = 0; j < contourLineSegments[i].size(); j += 2)
|
||||
{
|
||||
unorderedSegments.push_back(std::make_pair(contourLineSegments[i][j], contourLineSegments[i][j + 1]));
|
||||
}
|
||||
|
||||
std::deque<cvf::Vec2d> closedPolygonDeque;
|
||||
while (!unorderedSegments.empty())
|
||||
{
|
||||
bool expandedPolygon = false;
|
||||
for (auto listIt = unorderedSegments.begin(); listIt != unorderedSegments.end(); ++listIt)
|
||||
{
|
||||
if (closedPolygonDeque.empty() || listIt->first == closedPolygonDeque.back())
|
||||
{
|
||||
closedPolygonDeque.push_back(listIt->first);
|
||||
closedPolygonDeque.push_back(listIt->second);
|
||||
unorderedSegments.erase(listIt);
|
||||
expandedPolygon = true;
|
||||
break;
|
||||
}
|
||||
else if (listIt->second == closedPolygonDeque.back())
|
||||
{
|
||||
closedPolygonDeque.push_back(listIt->second);
|
||||
closedPolygonDeque.push_back(listIt->first);
|
||||
unorderedSegments.erase(listIt);
|
||||
expandedPolygon = true;
|
||||
break;
|
||||
}
|
||||
else if (listIt->first == closedPolygonDeque.front())
|
||||
{
|
||||
closedPolygonDeque.push_front(listIt->first);
|
||||
closedPolygonDeque.push_front(listIt->second);
|
||||
unorderedSegments.erase(listIt);
|
||||
expandedPolygon = true;
|
||||
break;
|
||||
}
|
||||
else if (listIt->second == closedPolygonDeque.front())
|
||||
{
|
||||
closedPolygonDeque.push_front(listIt->second);
|
||||
closedPolygonDeque.push_front(listIt->first);
|
||||
unorderedSegments.erase(listIt);
|
||||
expandedPolygon = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!expandedPolygon || unorderedSegments.empty())
|
||||
{
|
||||
if (closedPolygonDeque.back() != closedPolygonDeque.front())
|
||||
{
|
||||
closedPolygonDeque.push_back(closedPolygonDeque.back());
|
||||
closedPolygonDeque.push_back(closedPolygonDeque.front());
|
||||
}
|
||||
|
||||
// Make sure it is counter clockwise. Use Shoelace formula to calculate signed area.
|
||||
// https://en.wikipedia.org/wiki/Shoelace_formula
|
||||
double signedArea = 0.0;
|
||||
for (size_t j = 0; j < closedPolygonDeque.size() - 1; ++j)
|
||||
{
|
||||
signedArea += (closedPolygonDeque[j + 1].x() - closedPolygonDeque[j].x()) *
|
||||
(closedPolygonDeque[j + 1].y() + closedPolygonDeque[j].y());
|
||||
}
|
||||
if (std::abs(signedArea) > areaThreshold)
|
||||
{
|
||||
if (signedArea < 0.0)
|
||||
{
|
||||
closedPolygonsPerLevel[i].emplace_back(closedPolygonDeque.rbegin(), closedPolygonDeque.rend());
|
||||
}
|
||||
else
|
||||
{
|
||||
closedPolygonsPerLevel[i].emplace_back(closedPolygonDeque.begin(), closedPolygonDeque.end());
|
||||
}
|
||||
}
|
||||
closedPolygonDeque.clear();
|
||||
}
|
||||
unorderedSegments.push_back(std::make_pair(cvf::Vec3d(contourLineSegments[i][j]), cvf::Vec3d(contourLineSegments[i][j + 1])));
|
||||
}
|
||||
listOfSegmentsPerLevel[i] = unorderedSegments;
|
||||
}
|
||||
}
|
||||
return closedPolygonsPerLevel;
|
||||
|
||||
return listOfSegmentsPerLevel;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -25,9 +25,11 @@
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfVector2.h"
|
||||
#include "cvfVector3.h"
|
||||
|
||||
#include <deque>
|
||||
#include <limits>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
namespace caf
|
||||
@@ -35,14 +37,13 @@ namespace caf
|
||||
class ContourLines
|
||||
{
|
||||
public:
|
||||
typedef std::vector<cvf::Vec2d> ClosedPolygon;
|
||||
typedef std::vector<ClosedPolygon> ClosedPolygons;
|
||||
typedef std::pair<cvf::Vec3d, cvf::Vec3d> LineSegment;
|
||||
typedef std::list<LineSegment> ListOfLineSegments;
|
||||
|
||||
static std::vector<ClosedPolygons> create(const std::vector<double>& dataXY,
|
||||
const std::vector<double>& xPositions,
|
||||
const std::vector<double>& yPositions,
|
||||
const std::vector<double>& contourLevels,
|
||||
double areaTreshold = std::numeric_limits<double>::infinity());
|
||||
static std::vector<ListOfLineSegments> create(const std::vector<double>& dataXY,
|
||||
const std::vector<double>& xPositions,
|
||||
const std::vector<double>& yPositions,
|
||||
const std::vector<double>& contourLevels);
|
||||
|
||||
private:
|
||||
static void create(const std::vector<double>& dataXY,
|
||||
|
||||
Reference in New Issue
Block a user