Liagson/ConcaveHullGenerator

ArgumentOutOfRangeException

Closed this issue · 24 comments

Hi,
I am trying to use concavity diferent than 1 and I am getting error.
Points which I am using are here "dot_list" points.txt
Graphical image of points points

//geometry
List<Position> lineCoordinates2 = new List<Position>();
int scaleFactor = 1;
double concavity = 0; 
bool isSquareGrid = false;

Hull.setConvHull(dot_list);
Hull.setConcaveHull(Math.Round(Convert.ToDecimal(concavity), 2), scaleFactor, isSquareGrid);

List<PointLatLng> coordinatesGeo = new List<PointLatLng>();
for (var i = 0; i < Hull.hull_concave_edges.Count; i++)
{
	for (var j = 0; j < Hull.hull_concave_edges[i].nodes.Length; j++)
	{
		PointLatLng myPosition = new PointLatLng(Hull.hull_concave_edges[i].nodes[j].x, Hull.hull_concave_edges[i].nodes[j].y);
		if (!coordinatesGeo.Contains(myPosition))
		{
			GPoint gp = MainForm.instance.gMapControl.FromLatLngToLocal(myPosition);
			int index = uav.getInsertIndex(coordinatesGeo, new Accord.Point(gp.X, gp.Y));
			if (index >= 0 && index <= coordinatesGeo.Count)
				coordinatesGeo.Insert(index, myPosition);
		}
	}
}

What I am doing wrong? Is the Node id important and I need to set it? Currently it fix the error but it does not help to calculate correct points according to concavity.

It looks like something is wrong with calculation, because if I move points a littlebit it calculate ok.
Picture Example2

Hmmmm, can you tell me the line where the exception is thrown?

PS: I updated the code after noticing I, sadly, used type decimal for operations (they are now doubles)
Yes, I've edited this message many times, I really can't express my shame.

I can still simulate exception, exception is thrown in function getHullNearbyNodes line

currentID = concave_hull[line_count].nodes[position].id;

Exception is thrown if i do not set id of Nodes, calling

dot_list.Add(new Node(wp.Lat, wp.Lng));
instead of
dot_list.Add(new Node(wp.Lat, wp.Lng, dot_list.Count));

Even with new code (double fix) the concavity = 0.5 does not have correct effect.

Example3

I fear the id is mandatory in order for the dots to be differentiated between each other. I need to check it when I have some free time, but I think I'll delete the (unused?) constructor with no id in order to avoid this issue. That being said, I will try to take a closer look to your problem soon.

By the way, I see this line in your code and I fear it is wrong:
for (var j = 0; j < Hull.hull_concave_edges[i].nodes.Length; j++)
That Length refers to the length (sort of, if you want the true length you will need to sqrt Length) of an edge, not to the nodes of an edge.

To draw previous picture I used code from Init.cs, so my code is relevant to reported bug so you can ignore my code in first message.
If you want to simulate the bug where concavity = 0.5 is not correctly display use my points from file in first message.

Looking at your file I see that you have "Num" and "id" variables (being the id variable always 0) Could that be the issue?

Yes that was the problem that I got exception (like I explained in previos posts) since node id was not set. Now node id is set as num (id are set as sequntial numbers) and exception is gone, but concavity parameter 0,5 don't have correct result.
As I can see the concavity = 0.5 works only in some cases. I made new files and screenshot so you will be able to debug faster.

Not working example:
image NotWorking
dot_list NotWorking.txt

Working example:
image Works
dot_list Working.txt

Can you show me how you pass the file data to dot_list? I've tried viewing how result but the coordinates are way too close (like 0.001 units close) to be shown clearly in the unity demo scene.

I use C# for my code, I draw points on the map with GMap.Net library so this are real Latitude, Longitude coordinates and added them to dot_list,

dot_list.Add(new Node(wp.Lat, wp.Lng, dot_list.Count));

for your example I export them with

for (var i = 0; i < dot_list.Count; i++)
	logger.Debug("id:" + dot_list[i].id + " x:" + dot_list[i].x + " y:" + dot_list[i].y);

Code to read file would be

string location = "C://Downloads//Working.txt";
string[] lines = File.ReadAllLines(location);
for (var i = 0; i < lines.Length; i++)
{
    if (string.IsNullOrEmpty(lines[i]))
        continue;
    string[] line = lines[i].Split(' ');
    int id = int.Parse(line[0].Split(':')[1]);
    double Lat = double.Parse(line[1].Split(':')[1]);
    double Lng = double.Parse(line[2].Split(':')[1]);
    dot_list.Add(new Node(Lat, Lng, id));
}

I hope you needed the code to read file to dot_list or I didn't understood your last message.

Did you already have had the opportunity to look for mistake in calculating concavity = 0.5?

I've been able to reproduce the error, but currently have no clue about the cause of it. With luck I'll have enough time this weekend to find the root of the problem 😖

Ok great, thanks.

I think I've fixed it and as far as I see there are no bugs now (*)
Major change that you need to bare in mind now:

  • Concavity now makes sense: setting concavity to -1 will be the same as saying you don't want concavities. Setting it to 1 will mean extreme 0º angle concavities are possible (avoid setting it to 1). Concavity equals to the cosine of a concave angle. If you can confirm my new changes are working fine for you I will upload the new documentation as soon as I can (Explaining all this in detail). Setting concavity to 0.5 seems fine to me.
  • isSquareGrid boolean is gone. The code always checks tangent lines.

(*): By fixed I mean I've redone pretty much everything because I couldn't understand my terrible legacy code.

HullResults

Hi again, did you even test it on my example points? This is even wors result then before...
concavity05
concavity1

Have you tried lowering the concavity? (Maybe to -0.5 or lower) or lowering the scaleFactor? That area, as far as I see, looks correct to me, but it looks like the concavity factor is too high/agressive

I tested:
image concavity1
int scaleFactor = 1;
double concavity = 1;

image concavity05
int scaleFactor = 1;
double concavity = 0.5;

Try setting concavity to a negative value (it goes from -1 to 1)

Ok that looks much better and I think now is ok
concavity-1
concavity-05

Happy to see it working :)
I'll leave this Issue open just in case you find something weird with the new changes. I'm sorry about not updating my documentation (I'll try this weekend)

I already asked this question in separate issue task but I didn't get the correct answer so I will try to ask differently.
Can you add a parameter for setting buffer, with buffer i would like to tell how much out of current point the new returned points should be.
I hope the image will explain
bufferExample

Can you create a separate issue for that enhancement (adding, if you can, more details)? I have a few questions regarding your suggestion, but I don't want to fill this thread with non bug-related replies 😅

Ok I have reopend the issue. Thanks for help.

@MartinStokelj by the way, have you experienced a performance improvement with the last changes? I'm really curious about it.

For my use all works ok, thank you again for the fix.

Nice. I'm closing this issue then :)