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); }
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); } } }