GEOS OverlayOp intersection operation - c++

I am using GEOS 3.6.2 to compute an intersection between two polygons. I was able to construct my polygons, but when I try to compute the intersection it won't work.
Compiling my program in Debug mode, I get the error message:
The inferior stopped because it received a signal from the operating
system.
Signal name : SIGSEG
Signal meaning : Segmentation fault
Any idea where I'm wrong?
Here is my code:
#include <geos/geom/Polygon.h>
#include <geos/geom/LinearRing.h>
#include <geos/geom/CoordinateSequenceFactory.h>
#include <geos/geom/GeometryFactory.h>
#include <geos/geom/Geometry.h>
#include <geos/operation/overlay/OverlayOp.h>
#include <iostream>
#include <array>
////////////////////////////////////////////////////////////////////////////////
geos::geom::Polygon* MakePoly(std::vector<std::vector<int>> const& polyCoords)
{
geos::geom::GeometryFactory* factory = geos::geom::GeometryFactory::create().get();
geos::geom::CoordinateSequence* temp = factory->getCoordinateSequenceFactory()->create((std::size_t) 0, 0);
std::vector<std::vector<int>>::const_iterator it_x = polyCoords.begin();
int size = it_x->size();
for (int i=0; i<size; i++)
{
temp->add(geos::geom::Coordinate(polyCoords[0][i], polyCoords[1][i]));
}
geos::geom::LinearRing *shell=factory->createLinearRing(temp);
//NULL in this case could instead be a collection of one or more holes
//in the interior of the polygon
return factory->createPolygon(shell,NULL);
}
////////////////////////////////////////////////////////////////////////////////
int main()
{
// Create geometry.
std::vector<std::vector<int>> polyCoords1 = {
{1, 1, 2, 2, 1, 1, 4, 5, 4, 1},
{1, 2, 2, 4, 4, 5, 5, 3, 1, 1}
};
geos::geom::Polygon* poly1 = MakePoly(polyCoords1);
std::vector<std::vector<int>> polyCoords2 = {
{4, 4, 6, 6, 4},
{1, 5, 5, 1, 1}
};
geos::geom::Polygon* poly2 = MakePoly(polyCoords2);
// Actually perform the operation.
geos::operation::overlay::OverlayOp intersection(poly1, poly2);
// Extracting the geometry of the intersection (position of the error).
geos::geom::Geometry* intersectionGeo = intersection.getResultGeometry( geos::operation::overlay::OverlayOp::OpCode::opINTERSECTION );
std::cout<<intersectionGeo->getArea()<<std::endl;
}

The problem in your code is getting the GeometryFactory pointer.
geos::geom::GeometryFactory::create() returns a smart pointer (std::unique_ptr) so after this line:
geos::geom::GeometryFactory* factory = geos::geom::GeometryFactory::create().get();
The unique_ptr returned by create is disposed.
Change that line with:
geos::geom::GeometryFactory::Ptr factory = geos::geom::GeometryFactory::create();
And the code works.

Related

Solving a C2039 error and a C3861 error using std::minmax_element

I'm newer to C++.
I've written the following line in a test function inside a standard VS2019 test project:
auto minAndMaxYards = std::minmax_element(simResults.begin(), simResults.end());
It yields both C2039 and C3861 errors for the minmax_element function even though intellisense recognizes it as a member of std, and I can peek its definition. I can't figure out what I'm missing. I've included the algorithm file as well at the top of the test project.
Is there a project setting that I don't have right?
Full error text:
C2039 'minmax_element': is not a member of 'std'
C3861 'minmax_element': identifier not found
Edit, including code in case it helps
#include <algorithm>
#include "pch.h"
#include "CppUnitTest.h"
#include "Playbook.h"
#include "PlaySim.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
std::string output;
using std::vector;
namespace FootballDynastyV20UnitTest
{
TEST_CLASS(PlaybookIO)
{
public:
TEST_METHOD(setAndGetPlayblookName)
{
Playbook testPlays;
string testName = "testPlays";
testPlays.setName(testName);
string name = testPlays.getName();
Assert::IsTrue(name == testName);
}
TEST_METHOD(addPlayIncrementsPlayNum)
{
Playbook testPlays;
string playName = "Play1";
int numDLine = 4;
int numLB = 3;
vector<int> playerPos = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 19 };
vector<int> playerStance = { 2, 1, 0, 0, 1, 2, 2, 3, 2, 3, 3 };
vector<int> playerBlitzGaps = { 0, 3, 0, 0, 3, 0, 0, 0, 0, 0, 0 };
testPlays.setName("testPlays");
testPlays.addPlay(playName, numDLine, numLB, playerPos, playerStance, playerBlitzGaps);
Assert::IsTrue(testPlays.getNumPlays() == 1);
}
TEST_METHOD(saveAndLoadPlayblook)
{
Playbook testPlays;
Playbook testPlaysLoad;
string playName = "Play1";
int numDLine = 4;
int numLB = 3;
vector<int> playerPos = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 19 };
vector<int> playerStance = { 2, 1, 0, 0, 1, 2, 2, 3, 2, 3, 3 };
vector<int> playerBlitzGaps = { 0, 3, 0, 0, 3, 0, 0, 0, 0, 0, 0 };
testPlays.setName("testPlays");
testPlays.addPlay(playName, numDLine, numLB, playerPos, playerStance, playerBlitzGaps);
testPlays.save();
testPlaysLoad.load(testPlays.getName());
Assert::IsTrue(testPlays == testPlaysLoad);
}
};
TEST_CLASS(PlaySimTesting)
{
public:
TEST_METHOD(playSimReturnsYdsGainedBetweenNegative10And40)
{
PlaySim newPlay;
int numSims = 2000;
int lwrBound = -10;
int uprBound = 40;
vector<int> simResults;
for (int i = 0; i < numSims; i++)
{
newPlay.Run();
simResults.push_back(newPlay.GetYds());
}
auto minAndMaxYards = std::minmax_element(simResults.begin(), simResults.end());
int actualMin = *minAndMaxYards.first;
int actualMax = *minAndMaxYards.second;
int yds = newPlay.GetYds();
Assert::IsTrue((actualMin >= lwrBound) && (actualMax <= uprBound));
}
};
}
Move #include "pch.h" to the top of the file. When using precompiled headers, the compiler ignores everything above this line. In your example, that would be #include <algorithm>, that's why std::minmax_element is not found.

How to define a C++ function in VTK

I'm new with C++ and VTK. I'm trying to get cells ID into a rectilinearGrid basic example. I'm using this code, but the compiler say that is wrong with the error that I wrote in comment
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkFloatArray.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRectilinearGrid.h>
#include <vtkRectilinearGridGeometryFilter.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <array>
int main()
{
vtkNew<vtkNamedColors> colors;
std::array<int, 16> x = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
std::array<int, 16> y = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
std::array<int, 16> z = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
// Create a rectilinear grid by defining three arrays specifying the
// coordinates in the x-y-z directions.
vtkNew<vtkFloatArray> xCoords;
for (auto&& i : x)
{
xCoords->InsertNextValue(i);
}
vtkNew<vtkFloatArray> yCoords;
for (auto&& i : y)
{
yCoords->InsertNextValue(i);
}
vtkNew<vtkFloatArray> zCoords;
for (auto&& i : z)
{
zCoords->InsertNextValue(i);
}
// The coordinates are assigned to the rectilinear grid. Make sure that
// the number of values in each of the XCoordinates, YCoordinates,
// and ZCoordinates is equal to what is defined in SetDimensions().
//
vtkNew<vtkRectilinearGrid> rgrid;
rgrid->SetDimensions(int(x.size()), int(y.size()), int(z.size()));
rgrid->SetXCoordinates(xCoords);
rgrid->SetYCoordinates(yCoords);
rgrid->SetZCoordinates(zCoords);
vtkCell* GetCell(vtkRectilinearGrid * rgrid, int i, int j, int k) //I SHOULD INSERT IN HERE ";" FOR
{ //CLOSING THE STATEMENT. BUT IN
int dims[3]; //THIS WAY THE FUNCTION PARAMETER
rgrid->GetDimensions(dims); // BEHIND WOULDN'T BE CONNECTED.
if (i < 0 || i > dims[0] - 1 ||
j < 0 || j > dims[1] - 1 ||
k < 0 || k > dims[2] - 1)
{
return NULL; // out of bounds!
}
int pos[3];
pos[0] = i;
pos[1] = j;
pos[2] = k;
vtkIdType id;
id = vtkStructuredData::ComputeCellId(dims, pos);
return rgrid->GetCell(id);
};
// Extract a plane from the grid to see what we've got.
vtkNew<vtkRectilinearGridGeometryFilter> plane;
plane->SetInputData(rgrid);
plane->SetExtent(0, 46, 16, 16, 0, 43);
vtkNew<vtkPolyDataMapper> rgridMapper;
rgridMapper->SetInputConnection(plane->GetOutputPort());
vtkNew<vtkActor> wireActor;
wireActor->SetMapper(rgridMapper);
wireActor->GetProperty()->SetRepresentationToWireframe();
wireActor->GetProperty()->SetColor(colors->GetColor3d("Black").GetData());
// Create the usual rendering stuff.
vtkNew<vtkRenderer> renderer;
vtkNew<vtkRenderWindow> renWin;
renWin->AddRenderer(renderer);
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
renderer->AddActor(wireActor);
renderer->SetBackground(1, 1, 1);
renderer->ResetCamera();
renderer->GetActiveCamera()->Elevation(30.0);
renderer->GetActiveCamera()->Azimuth(15.0);
renderer->GetActiveCamera()->Zoom(1.0);
renderer->SetBackground(colors->GetColor3d("Beige").GetData());
renWin->SetSize(600, 600);
// interact with data
renWin->Render();
iren->Start();
return EXIT_SUCCESS;
}
How could be fixed?
UPDATE 1: I have inserted an image of the compiling error. Should be inserted ";" for closing the statement before {}
UPDATE 2: the exact error is
Errore (attivo) E0065 expected ';' RGrid C:\vtk\VTK-8.2.0\Examples\DataManipulation\Cxx\RGrid.cxx 73
I'm using Visual Studio. I have tried to drop the last ";" but nothing change
UPDATE 3: I have uploaded all the code
You have defined your GetCell function inside the body of the main function, which is not allowed in C++. Only a declaration would be allowed inside the body, hence the compiler expects a semicolon after the function header.
Move the whole GetCell function block outside the main function. If that leads to problems you cannot solve ask another question about them.

How to reset two-dimensional array to its original form after sorting?

I am trying to reset 2D array to its original form after it's been sorted with a bubble sort. I need to reset it back to what it was before sorting. How do I do it? In case you have a question why an array is global. It's a school assignment and that's how our professor wants us to do it.
Here is my program:
#include<iostream>
using namespace std;
const int NUM_COLS=4;
const int NUM_ROWS=5;
int array[NUM_ROWS][NUM_COLS]={{5, 3, 2, 16},
{9, 8, 10, 17},
{4, 7, 11, 18},
{2, 5, 9, 12},
{7, 9, 4, 10}};
it sorts an array with bubbleSort
void bubbleSort(int row, int col){}
it is display array function header
void displayArray(){}
and here is main function
int main(){
cout<<"original array"<<endl;
displayArray();
bubbleSort(NUM_ROWS-1, NUM_COLS);
cout<<"\nbubble sort"<<endl;
displayArray();
reset();
displayArray();
return 0;
}
Now I need to reset an array back to original. I did this but it doesn't work.
void reset(){
int array[NUM_ROWS][NUM_COLS]={{5, 3, 2, 16},
{9, 8, 10, 17},
{4, 7, 11, 18},
{2, 5, 9, 12},
{7, 9, 4, 10}};
}
Your reset is declaring a new array (and doing nothing with it). You can't assign (=) C style arrays, so you will need something that looks different. If you can use std::array instead, you could assign in reset.
#include <array>
const int NUM_COLS=4;
const int NUM_ROWS=5;
std::array<std::array<int, NUM_ROWS>, NUM_COLS> values = {
{5, 3, 2, 16},
{9, 8, 10, 17},
{4, 7, 11, 18},
{2, 5, 9, 12},
{7, 9, 4, 10}};
// Other code probably remains unchanged
void reset() {
values = {
{5, 3, 2, 16},
{9, 8, 10, 17},
{4, 7, 11, 18},
{2, 5, 9, 12},
{7, 9, 4, 10}};
}
At which point you notice that you've got your bounds the wrong way round, and it should either be
const int NUM_COLS=5;
const int NUM_ROWS=4;
or a differently shaped array initialiser.
void reset(){
static int original[NUM_ROWS][NUM_COLS]={{5, 3, 2, 16},
{9, 8, 10, 17},
{4, 7, 11, 18},
{2, 5, 9, 12},
{7, 9, 4, 10}};
for (int i = 0; i < NUM_ROWS; i++)
memcpy(array[i], original[i], NUM_COLS * sizeof(int));
}
Not the prettiest thing, but this should work. Since that's how your professor wants you to do it, go for it ¯\_(ツ)_/¯
As I said in a comment, the easiest way to assign arrays is to wrap them in a structure. Voilà, suddenly C++ develops abilities it didn't even know it had inherited from C and copies arrays!1 Even nested, multi-dimensional arrays!
#include <iostream>
#include <iomanip>
#include <algorithm>
using namespace std;
const int NUM_COLS=4;
const int NUM_ROWS=5;
// Define a struct (i.e., a class with all public members)
// which has just a single member, the array. Note that this is
// only a *type* declaration, no object is created yet.
struct arrT
{
int array [NUM_ROWS][NUM_COLS];
};
// object creation.
arrT workArr;
void reset()
{
// The initialization value is hidden inside the function.
// static variables are initialized only once, for constant
// data at compile time.
static const arrT oriArr
{
{ {5, 3, 2, 16},
{9, 8, 10, 17},
{4, 7, 11, 18},
{2, 5, 9, 12},
{7, 9, 4, 10}
}
};
workArr = oriArr; // simple default assignment of structs
}
// The parameters are redundant.
void stdSort(int /*row*/, int /*col*/)
{
// Sort the 2D array as a one-dimensional sequence
// (which the elements are in memory).
// The algorithm expects iterators to the first and
// one-after-the-last elements in the sequence. Pointers
// to the elements in an array are perfectly good iterators.
std::sort(&workArr.array[0][0], &workArr.array[NUM_ROWS-1][NUM_COLS]);
}
void displayArray()
{
// The top-level elements of a 2D array are the rows...
for(auto &row: workArr.array)
{
// ... and the elements of the rows are ints.
// Note how the
// dimensions are known from the class declaration.
for(auto &el: row)
{
cout << setw(4) << el;
}
cout << "\n";
}
}
int main(){
cout << "Work array before initialization:\n";
displayArray();
reset(); // before, the values of the global array are 0.
cout<<"\nWork array after init:\n";
displayArray();
stdSort(NUM_ROWS, NUM_COLS);
cout<<"\nWork array after std sort"<<endl;
displayArray();
reset();
cout << "\nWork array after reset\n";
displayArray();
return 0;
}
1 Arrays are the only example I know of off the cuff where the memberwise assignment of the generated default assignment operator can assign a type which does not have a standalone assignment operator (which is the exact reason we jump through this hoop). Are there others?

Running error of SSE2 code in VS2013

I have the following SIMD code trying to run in vs2013. It can be well compiled but cannot run. Anyone knows why?
#include <cstdio>
#include <xmmintrin.h>
int main()
{
const size_t num = 7;
float a[num] = { 1, 2, 3, 4, 5, 6, 7 };
float b[num] = { 1, -1, -2, 1, -3, -2, 5 };
float c[num];
__m128 A, B, C;
A = _mm_load_ps(&a[0]); // <== crash here.
B = _mm_load_ps(&b[0]);
C = _mm_add_ps(A, B);
_mm_store_ps(&c[0], C);
return 0;
}
The address being loaded from or stored to using these intrinsics needs to be 16 byte aligned (divisible by 16). See
https://msdn.microsoft.com/en-us/library/zzd50xxt(v=vs.90).aspx
You should declare the variables a,b and c like this:
__declspec(align(16)) float a[num] = { 1, 2, 3, 4, 5, 6, 7 };

Member List implementation of different class not working

I can't seem to get the implementation of my member list correct. I want to DEFAULT initialize my Set members nyX and nyY, however I keep getting an error.
class Location
{
public:
vector<int> nyXv = { 0, 1, 2, 3, 4, 5};
vector<int> nyYv = { 0, 1, 2, 3, 4, 5 };
Set nyX(vector<int>);
Set nyY(vector<int>);
Location();
~Location();
};
Location::Location()
:nyX(nyXv), nyY(nyYv)
{
}
Look at this example
You can initialize you vectors like this:
class Location
{
public:
vector<int> nyXv;// = { 0, 1, 2, 3, 4, 5};
vector<int> nyYv;// = { 0, 1, 2, 3, 4, 5 };
///...
Location();
~Location();
};
static const int arrX[] = {0, 1, 2, 3, 4, 5};
static const int arrY[] = {0, 1, 2, 3, 4, 5};
Location::Location()
:nyXv(arrX, arrX + sizeof(arrX) / sizeof(arrX[0]) )
,nyYv(arrY, arrY + sizeof(arrY) / sizeof(arrY[0]))
{
}
P.S. Of course there are many ways to improve this code but it should give you an idea