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);
        }
Example #2
0
        public override void ClickSelection(Vector2 point)
        {
            if (LineX > 0)
            {
                _lastSelection = (_lastSelection + 1) % LineX;
                Vec3 vec = new Vec3((Vec2)point, 0);
                if (_velocity.Grid.InGrid(vec))
                {
                    Vector3[] line    = _integrator.IntegrateLineForRendering(vec).Points.ToArray();
                    Line      newLine = new Line()
                    {
                        Positions = line
                    };
                    var set = new LineSet(new Line[] { newLine })
                    {
                        Color = _flipColor? Vector3.UnitX : Vector3.UnitZ
                    };

                    set.Thickness *= 3;
                    var ball = new LineBall(Plane, set, LineBall.RenderEffect.DEFAULT, Colormap, false);
                    _selections.Add(ball);

                    if (_selections.Count > LineX)
                    {
                        _selections.RemoveAt(0);
                        _selectionsAngle.RemoveAt(0);
                        _steadySelection.RemoveAt(0);
                    }

                    Graph2D[] angle = FieldAnalysis.GetDistanceToAngle(_core, Vector2.Zero, new LineSet(new Line[] { newLine }));
                    Debug.Assert(angle.Length == 1);

                    for (int p = 0; p < newLine.Length; ++p)
                    {
                        Vector3 sph = FieldAnalysis.SphericalPosition(_core[0], (float)(angle[0].X[p] * 0.5f / Math.PI), angle[0].Fx[p]);
                        newLine[p] = new Vector3(sph.X, sph.Y, angle[0].X[p] - angle[0].X[0]);
                    }
                    set = new LineSet(new Line[] { newLine })
                    {
                        Color = _flipColor ? Vector3.UnitX : Vector3.UnitZ
                    };
                    set.Thickness *= 3;
                    ball           = new LineBall(Plane, set, LineBall.RenderEffect.DEFAULT, Colormap, false);
                    _selectionsAngle.Add(ball);

                    _integrator.Field       = _steadyField;
                    _integrator.MaxNumSteps = 50;
                    line    = _integrator.IntegrateLineForRendering(new Vec2(vec.X, vec.Y)).Points.ToArray();
                    newLine = new Line()
                    {
                        Positions = line
                    };
                    set = new LineSet(new Line[] { newLine })
                    {
                        Color = _flipColor ? Vector3.UnitX : Vector3.UnitZ
                    };
                    set.Thickness *= 3;
                    ball           = new LineBall(new Plane(Plane, Vector3.UnitZ * 0.1f), set, LineBall.RenderEffect.DEFAULT, Colormap, false);
                    _steadySelection.Add(ball);
                    _integrator.Field       = _velocity;
                    _integrator.MaxNumSteps = 10000;

                    _flipColor = !_flipColor;
                    //var set = new LineSet(_selections.ToArray()) { Color = _selections.Count % 2 == 0 ? Vector3.UnitX : Vector3.UnitY };
                    //_lines = new LineBall(Plane, set, LineBall.RenderEffect.DEFAULT, Colormap, false);
                }
            }
        }