protected override void FindBoundary() { if (LoadGraph("Okubo", out _okubo)) { _graph = new LineBall(_graphPlane, _graphData, LineBall.RenderEffect.HEIGHT, Colormap, Flat, SliceTimeMain); return; } float angleDiff = (float)((Math.PI * 2) / _numSeeds); float[] radii = new float[LineX]; float[] angles = new float[_numSeeds]; for (int seed = 0; seed < _numSeeds; ++seed) { float angle = seed * angleDiff; angles[seed] = angle; } for (int o = 0; o < LineX; ++o) { radii[o] = o * _lengthRadius / (LineX - 1); } Console.WriteLine($"=== Working on Okubo Slice {0} ===", SliceTimeMain); ComputeOkubo(radii, angles, out _okubo); //LineSet okuboLines = FieldAnalysis.WriteGraphToSun(_okubo, new Vector3(_selection, SliceTimeMain)); _rebuilt = true; BuildGraph(); WriteGraph("Okubo", _okubo); }
protected void SetupRenderer() { try { Renderable.Initialize(Device); FieldPlane.Initialize(); ColorMapping.Initialize(Device); PointCloud.Initialize(); LineBall.Initialize(); Mesh.Initialize(); Device.ImmediateContext.OutputMerger.SetTargets(_host.RenderTargetView); Device.ImmediateContext.Rasterizer.SetViewports(new Viewport(0, 0, _host.RenderTargetWidth, _host.RenderTargetHeight, 0.0f, 1.0f)); _renderables = new List <Renderable>(); Camera = new Camera(Device, ((float)_host.RenderTargetWidth) / _host.RenderTargetHeight); var desc = new RasterizerStateDescription { CullMode = CullMode.None, FillMode = FillMode.Solid }; Device.ImmediateContext.Rasterizer.State = RasterizerState.FromDescription(Device, desc); SetupCuda(); AlgorithmCuda.Initialize(ContextCuda, Device); FlowMapUncertain.Initialize(); CutDiffusion.Initialize(); LocalDiffusion.Initialize(); } catch (Exception e) { Console.WriteLine(e); } }
protected void MaskOnData() { if (_coherency == null || _selectionData == null) { return; } //Renderer.Singleton.Remove(_graph); //float dataRange = 80; //float rangeOffset = dataRange * 0.5f; //Graph2D[] maskGraph = new Graph2D[_coherency.Length]; //for (int angle = 0; angle < maskGraph.Length; ++angle) // maskGraph[angle] = Graph2D.Operate(_coherency[angle], _selectionData[angle], (b, a) => (Math.Max(0, a + rangeOffset + 1/*b*/ * (2 * dataRange)))); //LineSet maskedLines = FieldAnalysis.WriteGraphToSun(maskGraph, new Vector3(_selection.X, _selection.Y, SliceTimeMain)); //_graph = new LineBall(_graphPlane, maskedLines, LineBall.RenderEffect.HEIGHT, Colormap, true, SliceTimeMain); //_graph.LowerBound = SliceTimeMain; //_graph.UpperBound = SliceTimeMain + 4 * dataRange; //_graph.UsedMap = Colormap.ParulaSegmentation; LineSet lines = FieldAnalysis.WriteGraphToSun(_coherency, new Vector3(_selection.X, _selection.Y, SliceTimeMain)); _graph = new LineBall(_graphPlane, lines, LineBall.RenderEffect.HEIGHT, Colormap.Parula, true, SliceTimeMain); _graph.LowerBound = SliceTimeMain; _graph.UpperBound = SliceTimeMain + 80; // Compute area coherency. float overallCoherency = ComputeCoherency(_coherency, _selectionData); Console.WriteLine(String.Format("=== {0} Coherency is {1} / 80 = {2}===", _currentFileName, overallCoherency, overallCoherency / 80)); }
protected void MaskOnData() { if (_dataGraph == null || _selectionData == null) { return; } Renderer.Singleton.Remove(_graph); float rangeOffset = _rangeGraphData * 0.5f; Graph2D[] maskGraph = new Graph2D[_dataGraph.Length]; for (int angle = 0; angle < maskGraph.Length; ++angle) { maskGraph[angle] = Graph2D.Operate(_dataGraph[angle], _selectionData[angle], (b, a) => (Math.Max(0, a + rangeOffset + b * (2 * _rangeGraphData)))); } LineSet maskedLines = FieldAnalysis.WriteGraphToSun(maskGraph, new Vector3(_selection.X, _selection.Y, SliceTimeMain)); _graph = new LineBall(_graphPlane, maskedLines, LineBall.RenderEffect.HEIGHT, Colormap, true, SliceTimeMain); _graph.LowerBound = _minGraphData; _graph.UpperBound = _minGraphData + 4 * _rangeGraphData; _graph.UsedMap = Colormap.ParulaSegmentation; Renderer.Singleton.AddRenderable(_graph); }
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) { // if(angle[0].X[p] > _velocity.Size.T - 1) // { // newLine.Resize(p); // break; // } 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); } } }
protected override void FindBoundary() { float[] offsets = new float[LineX]; float[] angles = new float[LineX]; for (int o = 0; o < offsets.Length; ++o) { offsets[o] = AlphaStable + o * IntegrationTime; angles[o] = 0; } IntegrateCircles(offsets, angles, out _distanceAngleGraph, SliceTimeMain); // ~~~~~~~~~~~~ Get Boundary for Rendering~~~~~~~~~~~~~~~~~~~~~~~~ \\ _pathlines = new LineBall(_linePlane, _pathlinesTime, LineBall.RenderEffect.HEIGHT, ColorMapping.GetComplementary(Colormap), Flat); _graph = new LineBall(_graphPlane, FieldAnalysis.WriteGraphsToCircles(_distanceAngleGraph, new Vector3(_selection.X, _selection.Y, SliceTimeMain)), LineBall.RenderEffect.HEIGHT, Colormap, false); }
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 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> CoherencyMap() { List <Renderable> renderables = new List <Renderable>(10); int numLines = LineX; #region BackgroundPlanes if (_lastSetting == null || MeasureChanged || SliceTimeMainChanged || MemberMainChanged || CoreChanged) { if (_lastSetting == null && _cores == null || CoreChanged || MemberMainChanged) { // Trace / load cores. TraceCore(MemberMain, SliceTimeMain); if (_selectedCore >= 0) { ClickSelection(_selection); } } // Computing which field to load as background. int totalTime = Math.Min(RedSea.Singleton.NumSubstepsTotal, SliceTimeMain); int time = (totalTime * _everyNthTimestep) / RedSea.Singleton.NumSubsteps; int subtime = (totalTime * _everyNthTimestep) % RedSea.Singleton.NumSubsteps; _timeSlice = LoadPlane(MemberMain, time, subtime, true); _intersectionPlane = _timeSlice.GetIntersectionPlane(); } if (_lastSetting == null || SliceTimeReferenceChanged) { // Reference slice. int totalTime = Math.Min(RedSea.Singleton.NumSubstepsTotal, SliceTimeReference); int time = (totalTime * _everyNthTimestep) / RedSea.Singleton.NumSubsteps; int subtime = (totalTime * _everyNthTimestep) % RedSea.Singleton.NumSubsteps; _compareSlice = LoadPlane(MemberMain, time, subtime, true); } if (_lastSetting == null || ColormapChanged || ShaderChanged || WindowStartChanged || WindowWidthChanged) { _timeSlice.SetRenderEffect(Shader); _timeSlice.UsedMap = Colormap; _timeSlice.LowerBound = WindowStart; _timeSlice.UpperBound = WindowWidth + WindowStart; _compareSlice.SetRenderEffect(Shader); _compareSlice.UsedMap = Colormap; _compareSlice.LowerBound = WindowStart; _compareSlice.UpperBound = WindowWidth + WindowStart; } // First item in list: plane. renderables.Add(_timeSlice); #endregion BackgroundPlanes // Add Point to indicate clicked position. //renderables.Add(new PointCloud(_linePlane, new PointSet<Point>(new Point[] { new Point() { Position = new Vector3(_selection, SliceTimeMain), Color = new Vector3(0.7f), Radius = 0.4f } }))); bool rebuilt = false; if (_lastSetting == null || DiffusionMeasureChanged) { switch (DiffusionMeasure) { case RedSea.DiffusionMeasure.FTLE: _currentFileName = "FTLE"; break; case RedSea.DiffusionMeasure.Direction: _currentFileName = "Okubo"; break; default: _currentFileName = "Concentric"; break; } } // Recompute lines if necessary. if (numLines > 0 && ( _lastSetting == null || NumLinesChanged || _selectionChanged || SliceTimeMainChanged || DiffusionMeasureChanged)) { _graph = null; // Load selection if (LoadGraph(_currentFileName + "Selection", out _selectionData)) { // Is there a drawing saved? If not, make a new empty graph. if (!LoadGraph(_currentFileName + "Coherency", _selectedCore, out _coherency, out _graphData)) { if (_coherency == null || _coherency.Length != _selectionData.Length) { _coherency = new Graph2D[_selectionData.Length]; } for (int angle = 0; angle < _coherency.Length; ++angle) { _coherency[angle] = new Graph2D(_selectionData[angle].Length); for (int rad = 0; rad < _coherency[angle].Length; ++rad) { _coherency[angle].X[rad] = _selectionData[angle].X[rad]; _coherency[angle].Fx[rad] = 0; } } IntegrateLines(); } else { _stencilPathlines = new List <LineSet>(8); for (int toTime = 10; toTime <= 80; toTime += 10) { string pathlineName = RedSea.Singleton.DiskFileName + _currentFileName + string.Format("Pathlines_{0}_{1}.pathlines", SliceTimeMain, toTime); LineSet paths; GeometryWriter.ReadFromFile(pathlineName, out paths); _stencilPathlines.Add(paths); } } // Some weird things happening, maybe this solves offset drawing... It does. LineSet coherencyLines = FieldAnalysis.WriteGraphToSun(_coherency, new Vector3(_selection.X, _selection.Y, SliceTimeMain)); _coherencyDisk = new LineBall(_graphPlane, coherencyLines, LineBall.RenderEffect.HEIGHT, Colormap, true, SliceTimeMain); //_coherencyDisk.LowerBound = SliceTimeMain; //_coherencyDisk.UpperBound = SliceTimeMain + 80; MaskOnData(); } _selectionChanged = false; rebuilt = true; } // Recompute lines if necessary. if (numLines > 0 && ( _lastSetting == null || NumLinesChanged || FlatChanged || _selectionChanged || SliceTimeReferenceChanged || DiffusionMeasureChanged)) { _selectionDistRef = null; // Load selection if (LoadGraph(_currentFileName + "Selection", _selectedCore, out _selectionDataRef, out _graphData, SliceTimeReference)) { // Some weird things happening, maybe this solves offset drawing... It does. LineSet selectionLines = FieldAnalysis.WriteGraphToSun(_selectionDataRef, new Vector3(_selection.X, _selection.Y, SliceTimeReference)); _selectionDistRef = new LineBall(_graphPlane, selectionLines, LineBall.RenderEffect.HEIGHT, Colormap.Gray, true, SliceTimeReference); _selectionDistRef.LowerBound = SliceTimeReference; _selectionDistRef.UpperBound = SliceTimeReference + 1; if (SliceTimeReference % 10 == 0 && SliceTimeReference != 0) { _pathlinesTime = _stencilPathlines[SliceTimeReference / 10 - 1]; _pathlines = new LineBall(_graphPlane, _pathlinesTime, LineBall.RenderEffect.HEIGHT, Colormap.Heat, false); _pathlines.LowerBound = SliceTimeMain; _pathlines.UpperBound = 80; } } _selectionChanged = false; rebuilt = true; } // Add the lineball. if (_pathlines != null && !Flat) { renderables.Add(_pathlines); } if (_graph != null) { renderables.Add(_graph); } if (_selectionDistRef != null) { renderables.Add(_selectionDistRef); } //if (_coherencyDisk != null) // && !Graph && !Flat) // renderables.Add(_coherencyDisk); // if (_selectionDistRef != null && (Graph || Flat)) // renderables.Add(_selectionDistRef); //if (SliceTimeMain != SliceTimeReference) // renderables.Add(_compareSlice); if (_selectedCore >= 0 && _coreBall != null && !Flat) { renderables.Add(_coreBall); } return(renderables); }
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 void TubeToRenderables() { if (_tube.Count < 1) return; _tube = _tube.OrderBy(o => o[0].Z).ToList(); //_boundaryBallSpacetime = new LineBall(new Plane(_graphPlane, Vector3.UnitZ * 0.01f), _boundariesSpacetime, LineBall.RenderEffect.HEIGHT, ColorMapping.GetComplementary(Colormap), Flat); LineSet rings = new LineSet(_tube.ToArray()); rings.Thickness *= 0.5f; _boundaryBallSpacetime = new LineBall(_linePlane, rings, LineBall.RenderEffect.HEIGHT, ColorMapping.GetComplementary(Colormap), false); //if (_tube.Count > 1) // _specialObject = new Mesh(_linePlane, new TileSurface(rings), Mesh.RenderEffect.DEFAULT, Colormap); }
protected Line Boundary(int timestep) { float cutValue = 2000.0f; // Compute error. if (LineX == 0) return null; _errorGraph = new Graph2D[_numSeeds]; _allBoundaryPoints = new List<Point>(); for (int seed = 0; seed < _numSeeds; ++seed) { // Smaller field: the difference diminishes it by one line. float[] fx = new float[LineX-1]; float[] x = new float[LineX-1]; for (int e = 0; e < fx.Length; ++e) { // Inbetween graphs, there is one useless one. int index = seed * LineX + e; if (_distanceDistance[index].Length <= 1) { fx[e] = cutValue * 1.5f; x[e] = _distanceDistance[index].Offset; } else { fx[e] = _distanceDistance[index].RelativeSumOver(IntegrationTime);// / _distanceDistance[index].Length; if (float.IsNaN(fx[e]) || float.IsInfinity(fx[e]) || fx[e] == float.MaxValue) fx[e] = 0; x[e] = _distanceDistance[index].Offset; //if (fx[e] > cutValue) //{ // Array.Resize(ref fx, e); // Array.Resize(ref x, e); // break; //} } } _errorGraph[seed] = new Graph2D(x, fx); _errorGraph[seed].SmoothLaplacian(0.8f); _errorGraph[seed].SmoothLaplacian(0.8f); } // Do whatever this methode does. LineSet line = FieldAnalysis.FindBoundaryInErrors3(_errorGraph, new Vector3(_selection, timestep)); string ending = "Bound_" + _numSeeds + '_' + AlphaStable + '_' + _lengthRadius + '_' + StepSize + '_' + _methode + '_' + timestep + ".ring"; Debug.Assert(line.Length == 1); // Directly rescale in Z. if (line[0][0].Z != timestep) { for (int p = 0; p < line[0].Length; ++p) { line[0].Positions[p].Z = timestep; } } GeometryWriter.WriteToFile(RedSea.Singleton.RingFileName + ending, line); foreach(Line l in line.Lines) _tube.Add(l); // ~~~~~~~~~~~~ Get Boundary for Rendering ~~~~~~~~~~~~ \\ // Show the current graph. _graph = new LineBall(_graphPlane, FieldAnalysis.WriteGraphToSun(_errorGraph, new Vector3(_selection.X, _selection.Y, timestep)), LineBall.RenderEffect.HEIGHT, Colormap, false); _rebuilt = false; if (line.Length != 1) Console.WriteLine("Not exactly one boundary!"); if (line.Length < 1) return null; return line[0]; }
protected override void UpdateBoundary() { if (_lastSetting != null && (_rebuilt || FlatChanged || GraphChanged)) { Graph2D[] dist = FieldAnalysis.GraphDifferenceForward(_distanceAngleGraph); Plane zPlane = new Plane(_graphPlane, Vector3.UnitZ * 2); _graph = new LineBall(_graphPlane, FieldAnalysis.WriteGraphToSun(_errorGraph, new Vector3(_selection.X, _selection.Y, 0)), LineBall.RenderEffect.HEIGHT, Colormap, Flat); // _graph = new LineBall(zPlane, FieldAnalysis.WriteGraphsToCircles(dist, new Vector3(_selection.X, _selection.Y, SliceTimeMain)), LineBall.RenderEffect.HEIGHT, Colormap, false); _rebuilt = false; } if (_lastSetting != null && (IntegrationTimeChanged || _rebuilt || Graph && GraphChanged && Flat)) BuildGraph(); //_graph = new LineBall(_graphPlane, FieldAnalysis.WriteGraphToSun(_errorGraph, new Vector3(_selection.X, _selection.Y, 0)), LineBall.RenderEffect.HEIGHT, Colormap, false); // new LineBall(_graphPlane, FieldAnalysis.WriteGraphsToCircles(_distanceAngleGraph, new Vector3(_selection.X, _selection.Y, SliceTimeMain)), LineBall.RenderEffect.HEIGHT, Colormap, false); //LineSet cutLines; ////if (SliceTimeReference > SliceTimeMain) ////{ //// // _graph = cut version of _coreAngleGraph. //// int length = SliceTimeReference - SliceTimeMain; //// length = (int)((float)length / StepSize + 0.5f); //// cutLines = FieldAnalysis.CutLength(new LineSet(_coreDistanceGraph), length); ////} ////else //// cutLines = new LineSet(_coreDistanceGraph); //cutLines = new LineSet(FieldAnalysis.); //_graph = new LineBall[] { new LineBall(_graphPlane, cutLines, LineBall.RenderEffect.HEIGHT, Colormap) }; }
public virtual void UpdateSelection() { if (_intersectionPlane == null) return; Vector2[] points = Renderer.Singleton.Camera.IntersectPlane(_intersectionPlane); Renderer.Singleton.Remove(_selectionRect); if (points == null) return; Vector3[] corners = new Vector3[5]; corners[0] = new Vector3(points[0], 0); corners[1] = new Vector3(points[0].X, points[1].Y, 0); corners[2] = new Vector3(points[1], 0); corners[3] = new Vector3(points[1].X, points[0].Y, 0); corners[4] = corners[0]; _selectionRect = new LineBall(_intersectionPlane, new LineSet(new Line[] { new Line() { Positions = corners } }) { Thickness = 0.2f, Color = Vector3.UnitX }); Renderer.Singleton.AddRenderable(_selectionRect); }
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); } } }
protected void BuildGraph() { // Compute ftle. if (LineX == 0) { return; } _graphData = FieldAnalysis.WriteGraphToSun(_okubo, new Vector3(_selection.X, _selection.Y, 0)); _graph = new LineBall(_graphPlane, _graphData, LineBall.RenderEffect.HEIGHT, Colormap, Flat, SliceTimeMain); _graph.LowerBound = -0.05f; _graph.UpperBound = 0.05f; _rebuilt = false; // Load or compute selection by floodfill. Graph2D[] okuboSelection; LineSet okuboLines; if (LoadGraph("OkuboSelection", _selectedCore, out okuboSelection, out okuboLines)) { return; } // Floodfill. int numAngles = _okubo.Length; int numRadii = _okubo[0].Length; HashSet <Int2> toFlood = new HashSet <Int2>(); okuboSelection = new Graph2D[numAngles]; for (int angle = 0; angle < numAngles; ++angle) { toFlood.Add(new Int2(angle, 0)); okuboSelection[angle] = new Graph2D(numRadii); for (int r = 1; r < numRadii; ++r) { okuboSelection[angle].Fx[r] = 0; okuboSelection[angle].X[r] = _okubo[angle].X[r]; } } while (toFlood.Count > 0) { Int2 current = toFlood.Last(); toFlood.Remove(current); okuboSelection[current.X].Fx[current.Y] = 1; // In each direction, go negative and positive. for (int dim = 0; dim < 2; ++dim) { for (int sign = -1; sign <= 1; sign += 2) { Int2 neighbor = new Int2(current); neighbor[dim] += sign; // Wrap angle around. neighbor[0] = (neighbor[0] + numAngles) % numAngles; if (neighbor.Y >= 0 && neighbor.Y < numRadii && _okubo[neighbor.X].Fx[neighbor.Y] <= 0 && okuboSelection[neighbor.X].Fx[neighbor.Y] == 0) { toFlood.Add(neighbor); } } } } LineSet sun = FieldAnalysis.WriteGraphToSun(okuboSelection, new Vector3(_selection, SliceTimeMain)); WriteGraph("OkuboSelection", _selectedCore, okuboSelection, sun); }
protected void BuildGraph() { float cutValue = 2000.0f; // Compute error. if (LineX == 0) return; if(_errorGraph == null || _errorGraph.Length != _numSeeds + 1) _errorGraph = new Graph2D[_numSeeds]; _allBoundaryPoints = new List<Point>(); for (int seed = 0; seed < _numSeeds; ++seed) { // Smaller field: the difference diminishes it by one line. float[] fx = new float[LineX - 1]; float[] x = new float[LineX - 1]; for (int e = 0; e < fx.Length; ++e) { // Inbetween graphs, there is one useless one. int index = seed * LineX + e; if (_distanceDistance[index].Length <= 1) { fx[e] = -0.01f; x[e] = _distanceDistance[index].Offset; } else { fx[e] = _distanceDistance[index].RelativeSumOver(IntegrationTime);// / _distanceDistance[index].Length; x[e] = _distanceDistance[index].Offset; if (fx[e] > cutValue || float.IsNaN(fx[e]) || float.IsInfinity(fx[e])) { fx[e] = 0.01f; } } } _errorGraph[seed] = new Graph2D(x, fx); _errorGraph[seed].SmoothLaplacian(0.8f); _errorGraph[seed].SmoothLaplacian(0.8f); //var maxs = _errorGraph[seed].Maxima(); //float angle = (float)((float)seed * Math.PI * 2 / _errorGraph.Length); //foreach (int p in maxs) //{ // float px = _errorGraph[seed].X[p]; // _allBoundaryPoints.Add(new Point(new Vector3(_selection.X + (float)(Math.Sin(angle + Math.PI / 2)) * px, _selection.Y + (float)(Math.Cos(angle + Math.PI / 2)) * px, cutValue)) { Color = Vector3.UnitX }); //} //int[] errorBound = FieldAnalysis.FindBoundaryInError(_errorGraph[seed]); //foreach (int bound in errorBound) // _allBoundaryPoints.Add(new Point(_pathlinesTime[seed * LineX + bound][0])); } //_boundariesSpacetime = FieldAnalysis.FindBoundaryInErrors(_errorGraph, new Vector3(_selection, SliceTimeMain)); //_boundaryBallSpacetime = new LineBall(_linePlane, _boundariesSpacetime, LineBall.RenderEffect.HEIGHT, ColorMapping.GetComplementary(Colormap)); //if (errorBound >= 0) // _allBoundaryPoints.Add(new Point(_pathlinesTime[seed * LineX + errorBound][0])); //GeometryWriter.WriteGraphCSV(RedSea.Singleton.DonutFileName + "Error.csv", _errorGraph); //Console.WriteLine("Radii without boundary point: {0} of {1}", _numSeeds - _allBoundaryPoints.Count, _numSeeds); //// _graphPlane.ZAxis = Plane.ZAxis * WindowWidth; //_boundaryCloud = new PointCloud(_graphPlane, new PointSet<Point>(_allBoundaryPoints.ToArray())); //LineSet lineCpy = new LineSet(_pathlinesTime); //lineCpy.CutAllHeight(_repulsion); //_pathlines = new LineBall(_linePlane, lineCpy, LineBall.RenderEffect.HEIGHT, Colormap, false); //int errorBound = FieldAnalysis.FindBoundaryInError(_errorGraph[0]); //_pathlinesTime.Cut(errorBound); // ~~~~~~~~~~~~ Get Boundary for Rendering ~~~~~~~~~~~~ \\ // _pathlines = new LineBall(_linePlane, _pathlinesTime, LineBall.RenderEffect.HEIGHT, ColorMapping.GetComplementary(Colormap), Flat); // _graph = new LineBall(_graphPlane, FieldAnalysis.WriteGraphsToCircles(_distanceAngleGraph, new Vector3(_selection.X, _selection.Y, SliceTimeMain)), LineBall.RenderEffect.HEIGHT, Colormap, false); _graph = new LineBall(_graphPlane, FieldAnalysis.WriteGraphToSun(_errorGraph, new Vector3(_selection.X, _selection.Y, 0)), LineBall.RenderEffect.HEIGHT, Colormap, Flat); LineSet line = FieldAnalysis.FindBoundaryInErrors3(_errorGraph, new Vector3(_selection, SliceTimeMain)); line.Thickness *= 0.5f; _boundaryBallSpacetime = new LineBall(_linePlane, line, LineBall.RenderEffect.HEIGHT, Colormap, false); _rebuilt = false; }
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; }