//Note that the value cache at grid vertices are internal grid (1/2 width). //This allows caching values at edge and face center points. private float EvaluateAtInternalGrid(GridCoordinate coord) { var g = coord.GetGridLong(_size); var tryRead = ReadCache(g); if (tryRead.HasValue) { return(tryRead.Value); } else { var val = _function.Get(null, coord.ToVector() / 2); AddToCache(g, val); return(val); } }
public Vector3 CalculateOptimalPoint(GridCoordinate grid) { if (_optimalPoint.TryGetValue(grid.GetGridLong(_size), out var ret)) { return(ret); } var internalGrid = grid + grid; _optimizer.Reset(); for (var axis = 0; axis < 3; ++axis) { var edgeHalfDiff = _axisIncList[axis]; var edgeFullDiff = edgeHalfDiff + edgeHalfDiff; for (var i = 0; i < 4; ++i) { var low = internalGrid + _gridEdgeList[axis * 4 + i]; var high = low + edgeFullDiff; var lowVal = EvaluateAtInternalGrid(low); var highVal = EvaluateAtInternalGrid(high); if (Math.Sign(lowVal) != Math.Sign(highVal)) { var pos = (0 - lowVal) / (highVal - lowVal); //TODO simplify var r = pos * high.ToVector() + (1 - pos) * low.ToVector() - internalGrid.ToVector(); var g = Vector3.Normalize(EvaluateGradient(low + edgeHalfDiff)); _optimizer.AddCrossEdge(r / 2, g); } } } ret = grid.ToVector() + _optimizer.Optimize(); _optimalPoint.Add(grid.GetGridLong(_size), ret); return(ret); }