private bool IsDivisionRequired(SurfaceRenderStackFrame stackFrame, SurfaceFunc func)
{
// if some points are out of func domain (when grid cell located on domain edge), then use interpolated values
List<double> zValues = new List<double>(3);
for (int x1 = 0; x1 <= 2; x1 += 2)
for (int y1 = 0; y1 <= 2; y1 += 2)
{
if (stackFrame.Points[x1, y1].Z != null)
continue;
zValues.Clear();
for (int x2 = 0; x2 <= 2; x2 += 2)
for (int y2 = 0; y2 <= 2; y2 += 2)
{
if (stackFrame.Points[x2, y2].Z == null)
continue;
double? z = func(stackFrame.Points[x2, y2].X + (stackFrame.Points[x2, y2].X - stackFrame.Points[x1, y1].X) / 100,
stackFrame.Points[x2, y2].Y + (stackFrame.Points[x2, y2].Y - stackFrame.Points[x1, y1].Y) / 100);
if (z != null)
zValues.Add(stackFrame.Points[x2, y2].Z.Value + (stackFrame.Points[x2, y2].Z.Value - z.Value) * 100);
}
if (zValues.Count == 0)
return false;
double zAvg = zValues.Average();
stackFrame.Points[x1, y1].XLeftProj = GetXProj(stackFrame.Points[x1, y1].X, zAvg, true);
stackFrame.Points[x1, y1].XRightProj = GetXProj(stackFrame.Points[x1, y1].X, zAvg, false);
stackFrame.Points[x1, y1].YProj = GetYProj(stackFrame.Points[x1, y1].Y, zAvg);
}
// if adjacent points of grid with same x or y coordinate are projected to non-adjacent points on the screen, then divide grid cell on subcells
return IsDivisionRequired(stackFrame.Points[0, 0].XLeftProj, stackFrame.Points[0, 0].YProj, stackFrame.Points[2, 0].XLeftProj, stackFrame.Points[2, 0].YProj,
stackFrame.Points[2, 2].XLeftProj, stackFrame.Points[2, 2].YProj, stackFrame.Points[0, 2].XLeftProj, stackFrame.Points[0, 2].YProj) ||
IsDivisionRequired(stackFrame.Points[0, 0].XRightProj, stackFrame.Points[0, 0].YProj, stackFrame.Points[2, 0].XRightProj, stackFrame.Points[2, 0].YProj,
stackFrame.Points[2, 2].XRightProj, stackFrame.Points[2, 2].YProj, stackFrame.Points[0, 2].XRightProj, stackFrame.Points[0, 2].YProj);
}