Exemple #1
0
        public virtual Vector Sample(VectorField field, Vector position)
        {
            // Query relevant edges and their weights. Result varies with different grid types.
            int numCells = NumAdjacentPoints();

            float[] weights;
            int[]   indices = FindAdjacentIndices(position, out weights);

            Debug.Assert(indices.Length == weights.Length);

            Vector result = new Vector(0, field.NumVectorDimensions);

            // Add the other weightes grid points.
            for (int dim = 0; dim < indices.Length; ++dim)
            {
                Vector add = field.Sample(indices[dim]);
                if (add[0] == field.InvalidValue)
                {
                    return(new Vector(field.InvalidValue ?? float.MaxValue, field.NumVectorDimensions));
                }
                result += add * weights[dim];
            }

            return(result);
        }
Exemple #2
0
        public void SetRenderEffect(RenderEffect effect)
        {
            // Ad length texture.
            if (effect == RenderEffect.LIC_LENGTH && Effect != RenderEffect.LIC_LENGTH && _field != null)
            {
                VectorField length = new VectorField(_field, FieldAnalysis.VFLength, 1, false);
                this.AddScalar(length[0] as ScalarField);
            }
            // Remove length texture?
            else if (effect != RenderEffect.LIC_LENGTH && Effect == RenderEffect.LIC_LENGTH && _field != null)
            {
                ShaderResourceView[] cpy = _fieldTextures;
                _fieldTextures = new ShaderResourceView[cpy.Length - 1];
                Array.Copy(cpy, _fieldTextures, _fieldTextures.Length);
            }
            switch (effect)
            {
            case RenderEffect.LIC:
            case RenderEffect.LIC_LENGTH:
                //Debug.Assert(_fields.Length >= 2);
                this._technique = _planeEffect.GetTechniqueByName("RenderLIC" + _fieldTextures.Length);
                break;

            case RenderEffect.CHECKERBOARD:
                this._technique = _planeEffect.GetTechniqueByName("RenderChecker");
                break;

            case RenderEffect.CHECKERBOARD_COLORMAP:
                this._technique = _planeEffect.GetTechniqueByName("RenderCheckerTex" + _fieldTextures.Length);
                break;

            case RenderEffect.OVERLAY:
                this._technique = _planeEffect.GetTechniqueByName("Overlay" + _fieldTextures.Length);
                break;

            case RenderEffect.LAPLACE:
                this._technique = _planeEffect.GetTechniqueByName("Laplace" + _fieldTextures.Length);
                break;

            case RenderEffect.GRADIENT:
                this._technique = _planeEffect.GetTechniqueByName("Gradient" + _fieldTextures.Length);
                break;

            case RenderEffect.COLORMAP:
            default:
                this._technique = _planeEffect.GetTechniqueByName("RenderTex" + _fieldTextures.Length);
                break;
            }
            Effect = effect;
        }
Exemple #3
0
        public VectorField GetTimeSlice(int slice)
        {
            ScalarField[] slices = new ScalarField[Scalars.Length];
            for (int scalar = 0; scalar < Scalars.Length; ++scalar)
            {
                slices[scalar] = _scalarsUnsteady[scalar].GetTimeSlice(slice);
            }

            var result = new VectorField(slices);

            result.TimeSlice    = slice;
            result.InvalidValue = InvalidValue;
            return(result);
        }
Exemple #4
0
            public static Integrator CreateIntegrator(VectorField field, Type type, Line core = null, float force = 0.1f)
            {
                switch (type)
                {
                case Type.RUNGE_KUTTA_4:
                    return(new IntegratorRK4(field));

                case Type.REPELLING_RUNGE_KUTTA:
                    return(new IntegratorRK4Repelling(field, core, force));

                default:
                    return(new IntegratorEuler(field));
                }
            }
Exemple #5
0
        public static void TestCP()
        {
            Random         rnd   = new Random(DateTime.Today.Millisecond);
            RectlinearGrid grid  = new RectlinearGrid(new Index(2, 2));
            ScalarField    cell0 = new ScalarField(grid);
            ScalarField    cell1 = new ScalarField(grid);

            for (int tests = 0; tests < 100; ++tests)
            {
                for (int i = 0; i < 4; ++i)
                {
                    cell0.Data[i] = (float)rnd.NextDouble() - 0.5f;
                    cell1.Data[i] = (float)rnd.NextDouble() - 0.5f;
                }
                VectorField cell = new VectorField(new ScalarField[] { cell0, cell1 });
                //PointSet<Point> points = FieldAnalysis.ComputeCriticalPointsRegularAnalytical2D(cell);
            }
        }
Exemple #6
0
        public VectorField(VectorField field, VFJFunction function, int outputDim, bool needJacobian = true)
        {
            int scalars = outputDim;/*function(field.Sample(0), field.SampleDerivative(new Vector(0, field.Size.Length))).Length;*/

            _scalars = new ScalarField[scalars];
            FieldGrid gridCopy = field.Grid.Copy();

            // In case the input field was time dependant, this one is not. Still, we keep the size and origin of the time as new dimension!
            gridCopy.TimeDependant = false;

            for (int dim = 0; dim < scalars; ++dim)
            {
                Scalars[dim] = new ScalarField(gridCopy);
            }
            this.InvalidValue = field.InvalidValue;

            GridIndex indexIterator = new GridIndex(field.Size);

            foreach (GridIndex index in indexIterator)
            {
                Vector v = field.Sample((int)index);

                if (v[0] == InvalidValue)
                {
                    for (int dim = 0; dim < Scalars.Length; ++dim)
                    {
                        Scalars[dim][(int)index] = (float)InvalidValue;
                    }
                    continue;
                }

                SquareMatrix J         = needJacobian? field.SampleDerivative(index) : null;
                Vector       funcValue = function(v, J);

                for (int dim = 0; dim < Scalars.Length; ++dim)
                {
                    var vec = Scalars[dim];
                    Scalars[dim][(int)index] = funcValue[dim];
                }
            }
        }
        protected void ComputeOkubo(float[] radii, float[] angles, out Graph2D[] okuboData)
        {
            float integrationLength = 40; // IntegrationTime;

            // ~~~~~~~~~~~~~~~~~~ Initialize seed points. ~~~~~~~~~~~~~~~~~~~~ \\
            PointSet <Point> circle = new PointSet <Point>(new Point[radii.Length * angles.Length * 4]);

            okuboData = new Graph2D[angles.Length];
            if (_velocity.TimeOrigin > SliceTimeMain || _velocity.TimeOrigin + _velocity.Size.T < SliceTimeMain)
            {
                LoadField(SliceTimeMain, MemberMain, 1);
            }

            VectorField okuboField = new VectorField(_velocity.GetSlice(SliceTimeMain), FieldAnalysis.OkuboWeiss, 1);

            float mean, fill, standardDeviation;

            (okuboField.Scalars[0] as ScalarField).ComputeStatistics(out fill, out mean, out _standardDeviation);
            Console.WriteLine("Mean: " + mean + ", SD: " + _standardDeviation + ", valid cells: " + fill);

            for (int angle = 0; angle < angles.Length; ++angle)
            {
                okuboData[angle] = new Graph2D(radii.Length);
                for (int rad = 0; rad < radii.Length; ++rad)
                {
                    okuboData[angle].X[rad] = radii[rad];
                    float x   = (float)(Math.Sin(angles[angle] + Math.PI / 2));
                    float y   = (float)(Math.Cos(angles[angle] + Math.PI / 2));
                    Vec2  pos = new Vec2(_selection.X + x * radii[rad], _selection.Y + y * radii[rad]);

                    if (!okuboField.Grid.InGrid(pos) || !okuboField.IsValid(pos))
                    {
                        okuboData[angle].Fx[rad] = 1;
                        continue;
                    }
                    okuboData[angle].Fx[rad] = okuboField[0].Sample(pos) + 0.2f * _standardDeviation;
                }
            }
        }
Exemple #8
0
        /// <summary>
        /// Plane to display scalar/vector field data on. Condition: Fields domain is 2D.
        /// </summary>
        /// <param name="origin"></param>
        /// <param name="xAxis"></param>
        /// <param name="yAxis"></param>
        /// <param name="scale">Scaling the field extent.</param>
        /// <param name="field"></param>
        public FieldPlane(Plane plane, VectorField fields, RenderEffect effect = RenderEffect.DEFAULT, Colormap map = Colormap.Parula)
        {
#if DEBUG
            // Assert that the fields are 2 dimensional.
            foreach (Field field in fields.Scalars)
            {
                System.Diagnostics.Debug.Assert(field.Size.Length >= 2);
            }
#endif
            this._effect          = _planeEffect;
            this._vertexSizeBytes = 32;
            this._numVertices     = 6;
            this.UsedMap          = map;
            this._width           = fields[0].Size[0];
            this._height          = fields[0].Size[1];
            this._invalid         = fields.InvalidValue ?? float.MaxValue;
            this._field           = fields;

            // Setting up the vertex buffer.
            GenerateGeometry(plane, fields[0].Size.ToInt2(), fields.TimeSlice ?? 0);


            // Generating Textures from the fields.
            _fieldTextures = new ShaderResourceView[fields.Scalars.Length];
            for (int f = 0; f < _field.NumVectorDimensions; ++f)
            {
                Texture2D tex = ColorMapping.GenerateTextureFromField(_device, fields[f]);
                _fieldTextures[f] = new ShaderResourceView(_device, tex);
            }

            this.SetRenderEffect(effect);
            this._vertexLayout = new InputLayout(_device, _technique.GetPassByIndex(0).Description.Signature, new[] {
                new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
                new InputElement("TEXTURE", 0, Format.R32G32B32A32_Float, 16, 0)
            });
        }
        public PlaygroundMapper(Plane plane) : base(new Plane(plane, 1), new Int2(NUM_CELLS))
        {
            Mapping          = Map;
            _velocity        = Tests.CreateBowl(new Vec2(NUM_CELLS / 2, 0), NUM_CELLS, new Vec2(-10, 0), 22, 200);
            _selections      = new List <LineBall>(10);
            _selectionsAngle = new List <LineBall>(10);
            _steadySelection = new List <LineBall>(10);

            // Core.
            _core = new Line()
            {
                Positions = new Vector3[] { new Vector3(50, 100, 0), new Vector3(155, 100, _velocity.Size.T - 1) }
            };
            LineSet set = new LineSet(new Line[] { _core })
            {
                Color = new Vector3(0.2f)
            };

            set.Thickness *= 3;
            _coreBall      = new LineBall(plane, set, LineBall.RenderEffect.DEFAULT);

            // Straight core.
            set = new LineSet(new Line[] { new Line()
                                           {
                                               Positions = new Vector3[] { _core[0], _core[0] + Vector3.UnitZ * (_velocity.Size.T - 1) }
                                           } })
            {
                Color = new Vector3(0.2f)
            };
            set.Thickness    *= 3;
            _straightCoreBall = new LineBall(Plane, set);

            var center = Tests.CreatePerfect(new Vec2(0, 0), NUM_CELLS, new Vec2(0), 1, 200);

            _steadyField = center.GetTimeSlice(0); //[0] as ScalarField;
        }
        public List <Renderable> ShowPaths()
        {
            bool mapLines = false;

            // Setup an integrator.
            VectorField.Integrator intVF = VectorField.Integrator.CreateIntegrator(Velocity, _currentSetting.IntegrationType);
            intVF.MaxNumSteps = 10000;
            intVF.StepSize    = _currentSetting.StepSize;

            if (_lastSetting == null ||
                IntegrationTypeChanged ||
                StepSizeChanged)
            {
                // ~~~~~~~~~~~ Line Integration ~~~~~~~~~~~ \\
                // Clear the raw lines.
                int timeLength = Velocity.Size.T;
                _rawLines = new LineSet[Velocity.Size.T];

                // Initialize the firth
                _rawLines[0] = new LineSet(new Line[0]);
                ScalarField[] lengths = new ScalarField[timeLength];
                lengths[0] = new ScalarField(Velocity.ScalarsAsSFU[0].TimeSlices[0], (v, J) => 0);

                _minLength = new float[timeLength];
                _maxLength = new float[timeLength];

                // Integrate the path line segments between each neighboring pair of time slices.
                for (int time = 1; time < timeLength; ++time)
                {
                    _minLength[time] = float.MaxValue;
                    _maxLength[time] = float.MinValue;

                    // Integrate last points until next time slice.
                    _pathlineSegments[time - 1]       = intVF.Integrate(_intersectTimeSlices[time - 1], false, time)[0];
                    _pathlineSegments[time - 1].Color = Vector3.UnitZ * (float)time / timeLength;

                    //                    if(time == timeLength - 1)
                    _intersectTimeSlices[time] = _pathlineSegments[time - 1].GetValidEndPoints();//VectorField.Integrator.Status.BORDER);
                    //else
                    //    _intersectTimeSlices[time] = _pathlineSegments[time - 1].GetEndPoints(VectorField.Integrator.Status.TIME_BORDER);
                    _points[time] = new PointCloud(Plane, _intersectTimeSlices[time].ToBasicSet());

                    // Set all positions to 0, or invalid value.
                    lengths[time] = new ScalarField(lengths[time - 1], (s, g) => s, false);
                    int i = 0;
                    for (int p = 0; p < _intersectTimeSlices[time].Points.Length; ++p)
                    {
                        EndPoint pP = _intersectTimeSlices[time].Points[p];
                        ++i;
                        // Map floating position to int position.
                        int   iPos        = _fieldPositionOfValidCell[p];
                        float timeStepped = (pP.Position.Z - (time - 1));
                        lengths[time][iPos] += timeStepped > 0 ? pP.LengthLine / timeStepped : 0;
                        float tmp = lengths[time][iPos];
                        _minLength[time] = Math.Min(lengths[time][iPos], _minLength[time]);
                        _maxLength[time] = Math.Max(lengths[time][iPos], _maxLength[time]);


                        if (_minLength[time] < 0 || pP.Status != VectorField.Integrator.Status.TIME_BORDER)
                        {
                            i += 0;
                        }
                        //Console.WriteLine(lengths[time][iPos]);
                    }
                    Console.WriteLine("Integrated lines until time " + time);
                }

                lengths[0]    = new VectorField(Velocity.GetTimeSlice(0), FieldAnalysis.VFLength, 1, false).Scalars[0] as ScalarField;
                _minLength[0] = 0;
                _maxLength[0] = RedSea.Singleton.NumTimeSlices;
                _pathLengths  = new ScalarFieldUnsteady(lengths);
                mapLines      = true;
            }

            if (_lastSetting == null ||
                SliceTimeMainChanged ||
                ShaderChanged)
            {
                ScalarField f = _pathLengths.GetTimeSlice(_currentSetting.SliceTimeMain);
                f.TimeOrigin = 0;
                VectorField vecField;
                switch (_currentSetting.Shader)
                {
                case FieldPlane.RenderEffect.LIC:
                    VectorField slice = Velocity.GetTimeSlice(0);
                    slice.TimeSlice = 0;
                    vecField        = new VectorField(new Field[] { slice.Scalars[0], slice.Scalars[1], f });
                    break;

                case FieldPlane.RenderEffect.LIC_LENGTH:
                    vecField           = Velocity.GetTimeSlice(_currentSetting.SliceTimeMain);
                    vecField.TimeSlice = 0;
                    break;

                default:
                case FieldPlane.RenderEffect.COLORMAP:
                case FieldPlane.RenderEffect.DEFAULT:
                    vecField = new VectorField(new Field[] { f });
                    break;
                }
                _plane = new FieldPlane(Plane, vecField /*Velocity.GetSlice(_currentSetting.SliceTimeReference)*/, _currentSetting.Shader);
            }

            // The line settings have changed. Create new renderables from the lines.
            if (mapLines || LineSettingChanged)
            {
                _lines = new Renderable[_pathlineSegments.Length];

                switch (_currentSetting.LineSetting)
                {
                // Map the vertices to colored points.
                case RedSea.DisplayLines.POINTS_2D_LENGTH:
                    for (int i = 0; i < _pathlineSegments.Length; ++i)
                    {
                        PointSet <Point> linePoints = Velocity.ColorCodeArbitrary(_pathlineSegments[i], RedSea.DisplayLineFunctions[(int)_currentSetting.LineSetting]);
                        _lines[i] = new PointCloud(Plane, linePoints);
                    }
                    break;

                // Render as line.
                default:
                case RedSea.DisplayLines.LINE:
                    for (int i = 0; i < _pathlineSegments.Length; ++i)
                    {
                        _lines[i] = new LineBall(Plane, _pathlineSegments[i]);
                    }
                    break;
                }
            }

            // Set mapping values.
            //_plane.UpperBound = 0; //= (1 + _currentSetting.WindowWidth) * (_maxLength[_currentSetting.SliceTimeMain] - _minLength[_currentSetting.SliceTimeMain]) /2 + _minLength[_currentSetting.SliceTimeMain];
            _plane.UpperBound = _currentSetting.WindowWidth + _currentSetting.WindowStart; ///= _currentSetting.SliceTimeMain;
            //_plane.LowerBound = 0; //= (1 - _currentSetting.WindowWidth) * (_maxLength[_currentSetting.SliceTimeMain] - _minLength[_currentSetting.SliceTimeMain]) /2 + _minLength[_currentSetting.SliceTimeMain];
            _plane.LowerBound = _currentSetting.WindowStart;                               ///= _currentSetting.SliceTimeMain;
            _plane.UsedMap    = _currentSetting.Colormap;
            _plane.SetRenderEffect(_currentSetting.Shader);

            List <Renderable> result = new List <Renderable>(50);

            result.Add(_plane);
            switch (_currentSetting.Tracking)
            {
            case RedSea.DisplayTracking.LINE:
            case RedSea.DisplayTracking.LINE_POINTS:
                Renderable[] lines = new Renderable[_currentSetting.SliceTimeMain];
                Array.Copy(_lines, lines, _currentSetting.SliceTimeMain);
                result = result.Concat(lines).ToList();
                break;

            case RedSea.DisplayTracking.POINTS:
                result.Add(_points[_currentSetting.SliceTimeMain]);
                break;

            case RedSea.DisplayTracking.LINE_SELECTION:
                VectorField.StreamLine <Vector3> line = intVF.IntegrateLineForRendering(new Vec3(_startPoint.X, _startPoint.Y, 0));
                LineSet set = new LineSet(new Line[] { new Line()
                                                       {
                                                           Positions = line.Points.ToArray()
                                                       } });
                if (_currentSetting.Flat)
                {
                    set.FlattenLines(_currentSetting.SliceTimeMain);
                }
                result.Add(new LineBall(Plane, set));
                break;

            default:
                break;
            }

            return(result);
        }
Exemple #11
0
        public List <Renderable> ComputeStatistics()
        {
            List <Renderable> result = new List <Renderable>(200);

            result.Add(new FieldPlane(Plane, Velocity.GetTimeSlice(_currentSetting.SliceTimeMain), _currentSetting.Shader, _currentSetting.Colormap));

            if (!_initialized)
            {
                return(result);
            }



            result.Add(new LineBall(Plane, new LineSet(new Line[] { new Line()
                                                                    {
                                                                        Positions = new Vector3[] { _startSelection, _endSelection }
                                                                    } })));


            bool completelyNew = false;

            // ~~~~~~~~~~~~~~ Get new Start Points ~~~~~~~~~~~~~~ //
            if (_lastSetting == null ||
                SliceTimeMainChanged ||
                LineXChanged ||
                _selectionChanged)
            {
                int     numPoints   = _startSelection == null ? 0 : Math.Max(2, _currentSetting.LineX + 1);
                Point[] startPoints = new Point[numPoints];

                // Compute point positions (linear interpolation).
                for (int x = 0; x < numPoints; ++x)
                {
                    float t = (float)x / (numPoints - 1);
                    startPoints[x] = new Point()
                    {
                        Position = _startSelection * (1.0f - t) + _endSelection * t
                    };
                }
                _linePoints = new PointSet <Point>(startPoints);
                _values     = new float[_linePoints.Length];

                completelyNew = true;
            }

            // ~~~~~~~~~~~~ Compute Selected Measure ~~~~~~~~~~~~ //
            if (completelyNew ||
                MeasureChanged ||
                FlatChanged ||
                IntegrationTimeChanged ||
                IntegrationTypeChanged ||
                StepSizeChanged)
            {
                // ~~~~~~~~~~~~~ Compute Scalar FIeld ~~~~~~~~~~~~~~~ //
                ScalarField measure = null;
                switch (_currentSetting.Measure)
                {
                // Velocity Length / Pathline Length.
                case RedSea.Measure.VELOCITY:
                    measure = new VectorField(Velocity.GetTimeSlice(_currentSetting.SliceTimeMain), FieldAnalysis.VFLength, 1).Scalars[0] as ScalarField;
                    break;

                case RedSea.Measure.SURFACE_HEIGHT:
                    break;

                case RedSea.Measure.SALINITY:
                    break;

                case RedSea.Measure.TEMPERATURE:
                    break;

                case RedSea.Measure.DIVERGENCE:
                    measure = new VectorField(Velocity.GetTimeSlice(_currentSetting.SliceTimeMain), FieldAnalysis.Divergence, 1).Scalars[0] as ScalarField;
                    break;

                // Closeness of Pathline.
                case RedSea.Measure.DIVERGENCE_2D:
                    break;

                case RedSea.Measure.VORTICITY:
                    measure = new VectorField(Velocity.GetTimeSlice(_currentSetting.SliceTimeMain), FieldAnalysis.Vorticity, 1).Scalars[0] as ScalarField;
                    break;

                case RedSea.Measure.SHEAR:
                    measure = new VectorField(Velocity.GetTimeSlice(_currentSetting.SliceTimeMain), FieldAnalysis.Shear, 1).Scalars[0] as ScalarField;
                    break;
                }

                // ~~~~~~~~~~~~~~~~ Sample Field ~~~~~~~~~~~~~~~~~~~ //
                switch (_currentSetting.Measure)
                {
                // Velocity Length / Pathline Length.
                case RedSea.Measure.VELOCITY:
                    if (_currentSetting.IntegrationTime == 0)
                    {
                        for (int index = 0; index < _values.Length; ++index)
                        {
                            _values[index] = measure.Sample(((Vec3)_linePoints.Points[index].Position).ToVec2());
                        }
                    }
                    else
                    {
                        VectorField.Integrator integrator = VectorField.Integrator.CreateIntegrator(Velocity, _currentSetting.IntegrationType);
                        integrator.Direction = Sign.POSITIVE;
                        integrator.StepSize  = _currentSetting.StepSize;

                        LineSet line = integrator.Integrate(_linePoints, _currentSetting.Flat, _currentSetting.IntegrationTime)[0];
                        for (int index = 0; index < _values.Length; ++index)
                        {
                            _values[index] = line.Lines[index].LineLength;
                        }
                        result.Add(new LineBall(Plane, line));
                    }
                    break;

                // Simply sample a field.
                case RedSea.Measure.SURFACE_HEIGHT:
                case RedSea.Measure.SALINITY:
                case RedSea.Measure.TEMPERATURE:
                case RedSea.Measure.DIVERGENCE:
                case RedSea.Measure.VORTICITY:
                case RedSea.Measure.SHEAR:
                    for (int index = 0; index < _values.Length; ++index)
                    {
                        _values[index] = measure.Sample(((Vec3)_linePoints.Points[index].Position).ToVec2());
                    }
                    break;

                // Closeness of Pathline.
                case RedSea.Measure.DIVERGENCE_2D:

                    break;
                }
                completelyNew = true;
            }

            //if (completelyNew ||
            //    AlphaStableChanged ||
            //    LineSettingChanged)
            //{
            // ~~~~~~~~~~~~~~~~ Display the Graph ~~~~~~~~~~~~~~~ //
            result.Add(FieldAnalysis.BuildGraph(Plane, _linePoints, _values, _currentSetting.AlphaStable, _currentSetting.LineSetting));
            //}
            _selectionChanged = false;
            return(result);
        }
Exemple #12
0
 public IntegratorRK4Repelling(VectorField field, Line core, float outwardForce) : base(field)
 {
     Core  = core;
     Force = outwardForce;
 }
Exemple #13
0
 public IntegratorRK4(VectorField field) : base(field)
 {
 }
Exemple #14
0
 public IntegratorEuler(VectorField field)
 {
     Field = field;
 }