Hey there, I am currently working on a small icosahedron planet. I got pretty far in generating it. Here is a picture:
However, as u might be able to notice, the triangles vary slightly in size. The reason being that I use a for loop to linearly calculate the distance between each point along an edge of each of the 20 icosahedron faces. In other words, a LERP. Here is an image visualizing the icosahedron face:
Now does anyone know how to SLERP through it with a for loop?
Below is my current code responsible for the LERP. Note that I LERP between 0 and 1 as I have used normalized coordinates. like: vert[0] = (0,0), vert[1] = (1,0), vert[2] = (0,1)
TArray<FVector> UMyBlueprintFunctionLibrary::GenerateLocalVertices(TArray<int> TriangleVerts, TArray<FVector> GlobalVertices, int resolution)
{
TArray<FVector> LocalVertices;
int ArraySize = ((resolution + 2) * (resolution + 2) - (resolution + 2)) / 2;
FVector GetFirstVert = GlobalVertices[TriangleVerts[0]];
FVector GetSecondVert = GlobalVertices[TriangleVerts[1]];
FVector GetThirdVert = GlobalVertices[TriangleVerts[2]];
int index = 0;
for (int i = 0; i < resolution + 1; i++)
{
for (int j = 0; j < i+1; j++)
{
float localX = (float) i/resolution - (float) j/resolution;
float localY = (float) j/resolution;
float newX = (1 - localX - localY) * GetFirstVert.X + localX * GetSecondVert.X + localY * GetThirdVert.X;
float newY = (1 - localX - localY) * GetFirstVert.Y + localX * GetSecondVert.Y + localY * GetThirdVert.Y;
float newZ = (1 - localX - localY) * GetFirstVert.Z + localX * GetSecondVert.Z + localY * GetThirdVert.Z;
LocalVertices.Add(FVector(newX,newY,newZ));
index++;
}
}
return LocalVertices;
}
I tried implementing a arcsin to fix it, but i ran into a new problem
float localX = asin(2 * ((float)i / resolution - (float)j / resolution) - 1) / PI + 0.5f;
float localY = asin(2 * ((float)j / resolution) - 1) / PI + 0.5f;
float newX = (1 - localX - localY) * GetFirstVert.X + localX * GetSecondVert.X + localY * GetThirdVert.X;
float newY = (1 - localX - localY) * GetFirstVert.Y + localX * GetSecondVert.Y + localY * GetThirdVert.Y;
float newZ = (1 - localX - localY) * GetFirstVert.Z + localX * GetSecondVert.Z + localY * GetThirdVert.Z;
fixed it by moving it to a latter part in the code.
But the correction is definitely a bit too aggressive. this was the function I currently used to correct it:
Tried another method, but it still seems off at the poles:
and the formula:
and code:
float InnerRadius = Edge * (sqrt(10 + 2 * sqrt(5)) / 4);
float angle = 2 * tan((Edge / 2) / (InnerRadius));
int index = 0;
for (int i = 0; i < resolution + 1; i++)
{
for (int j = 0; j < i+1; j++)
{
float localX = (float) i/resolution - (float) j/resolution;
float localY = (float) j/resolution;
float q1 = (sin(localX * angle)) / (sin(angle));
float q2 = (sin(localY * angle)) / (sin(angle));
float newX = (sin((1 - localX - localY)*angle)/sin(angle)) * GetFirstVert.X + (sin(localX*angle)/sin(angle)) * GetSecondVert.X + (sin(localY*angle)/sin(angle)) * GetThirdVert.X;
float newY = (sin((1 - localX - localY) * angle) / sin(angle)) * GetFirstVert.Y + (sin(localX * angle) / sin(angle)) * GetSecondVert.Y + (sin(localY * angle) / sin(angle)) * GetThirdVert.Y;
float newZ = (sin((1 - localX - localY) * angle) / sin(angle)) * GetFirstVert.Z + (sin(localX * angle) / sin(angle)) * GetSecondVert.Z + (sin(localY * angle) / sin(angle)) * GetThirdVert.Z;
LocalVertices.Add(FVector(newX,newY,newZ));
index++;
}
}