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); }
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 List <Renderable> Map() { List <Renderable> result = new List <Renderable>(10); #region BackgroundPlane if (_bg == null) { _bg = new FieldPlane(Plane, _velocity.GetTimeSlice(0), Shader, Colormap); _steadyBG = new FieldPlane(Plane, _steadyField, Shader, Colormap); } _bg.SetRenderEffect(Shader); _bg.UsedMap = Colormap; _bg.LowerBound = WindowStart; _bg.UpperBound = WindowStart + WindowWidth; _steadyBG.SetRenderEffect(Shader); _steadyBG.UsedMap = Colormap; _steadyBG.LowerBound = WindowStart; _steadyBG.UpperBound = WindowStart + WindowWidth; result.Add(Graph? _steadyBG : _bg); #endregion BackgroundPlane if (_lastSetting == null || IntegrationTypeChanged) { _integrator = VectorField.Integrator.CreateIntegrator(_velocity, IntegrationType); _integrator.StepSize = StepSize; } _integrator.StepSize = StepSize; if (_lastSetting != null && LineXChanged) { int diff = _selections.Count - LineX; if (diff > 0) { _selections.RemoveRange(0, diff); _selectionsAngle.RemoveRange(0, diff); //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); } } if (Flat) { result.AddRange(_selectionsAngle); result.Add(_straightCoreBall); } else if (!Graph) { result.AddRange(_selections); result.Add(_coreBall); } if (Graph) { result.AddRange(_steadySelection); } return(result); }