/** Triangulate between two polylines as if they where convex hulls, very similar to D&C merge * (Gift wrapping idea) from 3D Convex hull theory. Used for a tunnel start **/ public void triangulateTunnelStart(Polyline originPoly, Polyline destinyPoly) //TODO:some times does not triangulate correctly! //Start from a line between the first one of each polyline, by construction one is generated from the projection of the other=>NO as it has changed(smooth) { Vertex a = originPoly.getVertex(0); Vertex b = destinyPoly.getVertex(0); int aIndex = 1; int bIndex = 1; /*//For getting the starting line, using minimum distance points * //int j = 0; * float minDistance = Vector3.Distance (a.getPosition(), b.getPosition()); * for (int j = 0; j < originPoly.getSize (); ++j) { * for (int i = 0; i < destinyPoly.getSize (); ++i) { * float auxDistance = Vector3.Distance (originPoly.getVertex(j).getPosition (), destinyPoly.getVertex (i).getPosition ()); * if (auxDistance < minDistance) { * a = originPoly.getVertex (j); * b = destinyPoly.getVertex (i); * minDistance = auxDistance; * bIndex = i + 1; * aIndex = j + 1; * } * } * }*/ //Find lowerest tangent //The lower point of origin will be either the first or last vertex(by construction) /*if (a.getPosition ().y > originPoly.getVertex (-1).getPosition ().y) { * a = originPoly.getVertex (-1); * aIndex = 0; * } * int j = 0; * float minPos = float.MaxValue; * for (int i = 0; i < destinyPoly.getSize (); ++i) { * float auxPos = destinyPoly.getVertex (i).getPosition ().y; * if (auxPos < minPos) { * b = destinyPoly.getVertex (i); * minPos = auxPos; * bIndex = i + 1; * } * }*/ const int maxFoll = 5; int bFoll = 0, aFoll = 0; //To controll not the same sida is always the winner, as it produces artifacts some cases int bIter = 0, aIter = 0; bool aWins = false; while (aIter < originPoly.getSize() && bIter < destinyPoly.getSize()) { //This line ab will be triangulated with a point c either from one polyliline or the other, depending the one that has //smallest angle with ab line(A-winner or B-winner).c It's always an adjacent vertex, we can use they are clockwise sorted(lucky!) Vector3 ab = b.getPosition() - a.getPosition(); //Check the B polylilne candidate Vertex bWinner = destinyPoly.getVertex(bIndex); float bAngle = Vector3.Angle(-ab, bWinner.getPosition() - b.getPosition()); //Check the A polylilne candidate Vertex aWinner = originPoly.getVertex(aIndex); float aAngle = Vector3.Angle(ab, aWinner.getPosition() - a.getPosition()); //aAngle = Vector3.Distance (aWinner.getPosition (), b.getPosition ()); //bAngle = Vector3.Distance (bWinner.getPosition (), a.getPosition ()); //Check not same polyline accumulates too much wins if (aFoll > maxFoll) { aWins = false; aFoll = 0; } else if (bFoll > maxFoll) { aWins = true; bFoll = 0; } else { aWins = aAngle < bAngle; } //If it's A-winner(from first poly) a=c, if it's from b-Winner b = c if (aWins) //A wins! { addTriangle(a.getIndex(), aWinner.getIndex(), b.getIndex()); a = aWinner; ++aIndex; ++aIter; ++aFoll; } else //B wins! { addTriangle(a.getIndex(), bWinner.getIndex(), b.getIndex()); b = bWinner; ++bIndex; ++bIter; ++bFoll; } } //Repeat until ab we arrive to some of the polylines start, then triangulate with a or b constant(depends on polyline) if (aIter >= originPoly.getSize()) { while (bIter < destinyPoly.getSize()) { Vertex bWinner = destinyPoly.getVertex(bIndex); addTriangle(a.getIndex(), bWinner.getIndex(), b.getIndex()); b = bWinner; ++bIndex; ++bIter; } } else if (bIter >= destinyPoly.getSize()) { while (aIter < originPoly.getSize()) { Vertex aWinner = originPoly.getVertex(aIndex); addTriangle(a.getIndex(), aWinner.getIndex(), b.getIndex()); a = aWinner; ++aIndex; ++aIter; } } //TODO: check strange artifacts cases, //may be procuduced by winner decision, maybe smallest angle is not the best choice(or checking worng angle) }