private void RefreshPlane() { _dataMap = new FieldPlane[1]; switch (_currentSetting.Shader) { case FieldPlane.RenderEffect.LIC: { var tmp = _velocity.GetTimeSlice(_currentSetting.SliceTimeMain); tmp.TimeSlice = null; _dataMap[0] = new FieldPlane(_subrangePlane, tmp, _currentSetting.Shader, _currentSetting.Colormap); _dataMap[0].AddScalar(_diffusionMap.Map); RefreshBoundsPlanes(); break; } case FieldPlane.RenderEffect.LIC_LENGTH: { _dataMap = new FieldPlane[2]; var tmp = _velocity.GetTimeSlice(_currentSetting.SliceTimeMain); tmp.TimeSlice = null; _dataMap[0] = new FieldPlane(_subrangePlane, tmp, _currentSetting.Shader, ColorMapping.GetComplementary(_currentSetting.Colormap)); _dataMap[0].LowerBound = 0; _dataMap[0].UpperBound = 20; _dataMap[1] = new FieldPlane(_subrangePlane, _diffusionMap.Map, (_velocity.Size).ToInt2(), 0, 0, FieldPlane.RenderEffect.OVERLAY, _currentSetting.Colormap); _dataMap[1].LowerBound = 0; _dataMap[1].UpperBound = _currentSetting.WindowWidth; //if (_currentSetting.Shader == FieldPlane.RenderEffect.LIC) // _dataMap[0].AddScalar(_diffusionMap.ReferenceMap); break; } case FieldPlane.RenderEffect.OVERLAY: default: _dataMap[0] = _diffusionMap.GetPlane(_subrangePlane); _dataMap[0].UsedMap = _currentSetting.Colormap; _dataMap[0].SetRenderEffect(_currentSetting.Shader); RefreshBoundsPlanes(); break; } }
private void RefreshPlane() { switch (_currentSetting.Shader) { case FieldPlane.RenderEffect.LIC: case FieldPlane.RenderEffect.LIC_LENGTH: var tmp = _velocity.GetTimeSlice(_currentSetting.SliceTimeMain); tmp.TimeSlice = null; _currentState = new FieldPlane(_subrangePlane, tmp, _currentSetting.Shader, _currentSetting.Colormap); _currentState.AddScalar(_flowMap.FlowMap); break; default: _currentState = _flowMap.GetPlane(_subrangePlane); _currentState.UsedMap = _currentSetting.Colormap; _currentState.SetRenderEffect(_currentSetting.Shader); break; } }
public PathlineLengthMapper(VectorFieldUnsteady velocity, Plane plane) : base(plane, velocity.Size.ToInt2()) { Velocity = velocity; Mapping = ShowPaths; Plane = plane; int time = velocity.Size.T; _intersectTimeSlices = new PointSet <EndPoint> [time]; _pathlineSegments = new LineSet[time - 1]; _intersectTimeSlices[0] = FieldAnalysis.ValidDataPoints <EndPoint>(velocity.GetTimeSlice(0));//FieldAnalysis.SomePoints2D<EndPoint>(velocity, 100);// _points = new PointCloud[velocity.Size.T]; _points[0] = new PointCloud(Plane, _intersectTimeSlices[0].ToBasicSet()); _fieldPositionOfValidCell = new int[_intersectTimeSlices[0].Length]; for (int i = 0; i < _fieldPositionOfValidCell.Length; ++i) { Vector3 pos = _intersectTimeSlices[0].Points[i].Position; _fieldPositionOfValidCell[i] = (int)(pos.X + 0.5) + (int)(pos.Y + 0.5) * Velocity.Size[0]; } }
public PathlineLengthMapper(VectorFieldUnsteady velocity, Plane plane) : base(plane, velocity.Size.ToInt2()) { Velocity = velocity; Mapping = ShowPaths; Plane = plane; int time = velocity.Size.T; _intersectTimeSlices = new PointSet<EndPoint>[time]; _pathlineSegments = new LineSet[time - 1]; _intersectTimeSlices[0] = FieldAnalysis.ValidDataPoints<EndPoint>(velocity.GetTimeSlice(0));//FieldAnalysis.SomePoints2D<EndPoint>(velocity, 100);// _points = new PointCloud[velocity.Size.T]; _points[0] = new PointCloud(Plane, _intersectTimeSlices[0].ToBasicSet()); _fieldPositionOfValidCell = new int[_intersectTimeSlices[0].Length]; for(int i = 0; i < _fieldPositionOfValidCell.Length; ++i) { Vector3 pos = _intersectTimeSlices[0].Points[i].Position; _fieldPositionOfValidCell[i] = (int)(pos.X + 0.5) + (int)(pos.Y + 0.5) * Velocity.Size[0]; } }
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); }
protected override void TraceCore(int member = 0, int startSubstep = 0) { int rad = NEIGHBOORHOOD_CP * (Core == CoreAlgorithm.ROUGH_STREAM_CONNECTION ? 4 : 1); string corename = RedSea.Singleton.CoreFileName + member + Core.ToString() + "cc.line"; if (System.IO.File.Exists(corename)) { GeometryWriter.ReadFromFile(corename, out _cores); LoadField(0, MemberMain, 1); } else { Vec3[] bases = new Vec3[] { new Vec3(463.1f, 53.6f, 0), new Vec3(366.4f, 34.4f, 0), new Vec3(230.1f, 218.6f, 0)}; if (Core == CoreAlgorithm.CLICK) { Line[] lines = new Line[bases.Length]; for(int b = 0; b < bases.Length; ++b) lines[b] = new Line() { Positions = new Vector3[] { (Vector3)bases[b], (Vector3)bases[b] + Vector3.UnitZ * (float)(RedSea.Singleton.NumSubstepsTotal / _everyNthTimestep) } }; _cores = new LineSet(lines); LoadField(0, MemberMain, 1); return; } int numSlices = RedSea.Singleton.NumSubstepsTotal / _everyNthTimestep; int stepSize = Core != CoreAlgorithm.ROUGH_STREAM_CONNECTION ? 1 : ROUGH_MULTIPLIER; // RedSea.Singleton.NumSubstepsTotal / _everyNthTimestep - 1; _cores = new LineSet(new Line[bases.Length]); for (int b = 0; b < _cores.Length; ++b) { _cores[b] = new Line((int)Math.Ceiling((float)(numSlices -1)/ stepSize)+1); //_cores[b][0] = (Vector3)bases[b]; } int idx = 0; // Connect to other slices. for(int slice = 0; slice < numSlices; slice += stepSize) { LoadField(Math.Min(slice, numSlices - 2), member, 2); VectorField field = _velocity; if (Core == CoreAlgorithm.PATHLINE) { var acc= new VectorFieldUnsteady(_velocity, FieldAnalysis.Acceleration, 2); field = acc.GetTimeSlice(slice); } else { field = _velocity.GetTimeSlice(slice); } for (int b = 0; b < _cores.Length; ++b) { Vector3 lastCP = idx > 0? _cores[b][idx-1] : (Vector3)bases[b]; Int2 x = new Int2((int)lastCP.X - rad, (int)Math.Ceiling(lastCP.X) + rad); Int2 y = new Int2((int)lastCP.Y - rad, (int)Math.Ceiling(lastCP.Y) + rad); CriticalPointSet2D points = FieldAnalysis.ComputeCriticalPointsRegularSubdivision2DRange(field, x, y); float minDist = float.MaxValue; CriticalPoint2D nearest = null; foreach(CriticalPoint2D point in points.Points) { float dist = (lastCP - point.Position).LengthSquared(); if(dist< minDist) { minDist = dist; nearest = point; } } _cores[b][idx] = nearest?.Position ?? lastCP; _cores[b].Positions[idx].Z = slice; } idx++; // Reverse-engineered: Always include the last possible slice. if (slice + stepSize >= numSlices && slice + 1 < numSlices) slice = numSlices - 1 - stepSize; } GeometryWriter.WriteToFile(corename, _cores); } }
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> 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); }