예제 #1
0
        //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);
            }
        }
예제 #2
0
        private GridEdge FindFirst()
        {
            GridCoordinate g0    = new GridCoordinate(0, 0, 0);
            GridCoordinate gMove = new GridCoordinate(1, 0, 0);

            if (_cache.EvaluateAtGrid(g0, GridCoordinate.Zero) < 0)
            {
                throw new Exception("Origin not contained in shape");
            }
            var g1 = g0 + gMove;

            while (_cache.EvaluateAtGrid(g1, GridCoordinate.Zero) > 0)
            {
                g0  = g1;
                g1 += gMove;
            }
            return(new GridEdge(g0, 0));
        }
예제 #3
0
        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);
        }
예제 #4
0
 private int GetVertex(GridCoordinate grid)
 {
     return(_gridVertex[grid.GetGridLong(_size)]);
 }
예제 #5
0
 public GridEdge(GridCoordinate coord, int axis)
 {
     Coord = coord;
     Axis  = axis;
 }
예제 #6
0
 private float EvaluateDifference(GridCoordinate internalGrid, GridCoordinate diff)
 {
     return(EvaluateAtInternalGrid(internalGrid + diff) - EvaluateAtInternalGrid(internalGrid - diff));
 }
예제 #7
0
 public float EvaluateAtGrid(GridCoordinate coord, GridCoordinate halfOffset)
 {
     return(EvaluateAtInternalGrid(coord + coord + halfOffset));
 }