-2

I'm trying to implement a simple Delaunay Triangulation, from the lua file in the zip archive to C++.

Here's the original lua file

#include "delaunay.h"

#include <cmath>
#include <algorithm>  
#include <assert.h>

std::vector<Triangle> Delaunay::triangulate(std::vector<Vector2<float>> points)
{
    std::size_t npoints = points.size();
    int trmax = npoints * 4;

    float minX = points[0].getX();
    float minY = points[0].getY();
    float maxX = minX;
    float maxY = minY;

    for(std::size_t i = 0; i < points.size(); ++i) {
        points[i].id = i;
        if (points[i].getX() < minX) 
            minX = points[i].getX();
        if (points[i].getY() < minY)
            minY = points[i].getY();
        if (points[i].getX() > maxX)
            maxX = points[i].getX();
        if (points[i].getY() > maxY)
            maxY = points[i].getY();
    }

    float dx = maxX - minX;
    float dy = maxY - minY;
    float deltaMax = std::max(dx, dy);
    float midx = (minX + maxX) * 0.5;
    float midy = (minY + maxY) * 0.5;


    Vector2<float> p1(midx - 2 * deltaMax, midy - deltaMax);
    Vector2<float> p2(midx, midy + 2 * deltaMax);
    Vector2<float> p3(midx + 2 * deltaMax, midy - deltaMax);

    p1.id = npoints + 1;
    p2.id = npoints + 2;
    p3.id = npoints + 3;

    points.push_back(p1);
    points.push_back(p2);
    points.push_back(p3);

    std::vector<Triangle> triangles;
    triangles.push_back(Triangle(points[points.size() - 1], points[points.size() - 2], points[points.size() - 3]));

    for(std::size_t i = 0; i < npoints; ++i) {
        std::vector<Edge> edges;

        for(std::size_t j = triangles.size(); j-- > 0; ) {
            Triangle curTriangle = triangles[j];

            if(curTriangle.inCircumCircle(points[i])) {
                edges.push_back(curTriangle.getE1());
                edges.push_back(curTriangle.getE2());
                edges.push_back(curTriangle.getE3());
                triangles.erase(triangles.begin() + j);
            }
        }

        for(std::size_t j = edges.size() - 1; --j > 0; ) {
            for(std::size_t k = edges.size(); --k > j + 1; ) {
                if(edges[j].equals(edges[k])) {
                    edges.erase(edges.begin() + j); 
                    edges.erase(edges.begin() + k - 1);
                }
            }   
        }

        for(std::size_t j = 0; j < edges.size(); ++j) {
            int n = triangles.size();
            std::cout << n << " " << trmax << std::endl;
            assert(n <= trmax && "Generated more than needed triangles");   
            triangles.push_back(Triangle(edges[j].getP1(), edges[j].getP2(), points[i]));
        }
    }

    for(std::size_t i = triangles.size(); --i > 0; ) {
        Triangle triangle = triangles[i];
        if(triangle.getP1().id > static_cast<int>(npoints) ||
            triangle.getP2().id > static_cast<int>(npoints) ||
            triangle.getP3().id > static_cast<int>(npoints)) {
            triangles.erase(triangles.begin() + i);
        }
    }

    return triangles;
}

And here's what I got

/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../include/c++/5.2.0/debug/vector:406:
error: attempt to subscript container with out-of-bounds index 29, but 
container only holds 29 elements.

Objects involved in the operation:
    sequence "this" @ 0x0x7ffd71c01260 {
}
[1]    31657 abort (core dumped)  ./pudding

The problem is that I keep getting a load of out of bound indices, and when it works, the assert at the line 77 in the hastebin makes it crash.

This line is making it crash

if(edges[j].equals(edges[k])) 

Does anyone have an idea why is it not working? All the files are here if you want to take a look.

Thanks a lot.

Quentin
  • 62,093
  • 7
  • 131
  • 191
bl4ckb0ne
  • 1,097
  • 2
  • 15
  • 30

1 Answers1

0

When you generate new triangles you seem to include edges with the current point. This give the error. Make the new triangles vertices not all the current point.

Micromega
  • 12,486
  • 7
  • 35
  • 72
  • I don't understand what you're saying. Which points shoud I give to the constructor? – bl4ckb0ne Oct 06 '15 at 17:35
  • It's a rare condition but when you form new triangles with the new point it can happen the next point is in the circumcenter of 1 to many triangles. It is not easy computation. It can take long time. – Micromega Oct 06 '15 at 18:50