public virtual Vector Sample(VectorField field, Vector position) { // Query relevant edges and their weights. Result varies with different grid types. int numCells = NumAdjacentPoints(); float[] weights; int[] indices = FindAdjacentIndices(position, out weights); Debug.Assert(indices.Length == weights.Length); Vector result = new Vector(0, field.NumVectorDimensions); // Add the other weightes grid points. for (int dim = 0; dim < indices.Length; ++dim) { Vector add = field.Sample(indices[dim]); if (add[0] == field.InvalidValue) { return(new Vector(field.InvalidValue ?? float.MaxValue, field.NumVectorDimensions)); } result += add * weights[dim]; } return(result); }
public void SetRenderEffect(RenderEffect effect) { // Ad length texture. if (effect == RenderEffect.LIC_LENGTH && Effect != RenderEffect.LIC_LENGTH && _field != null) { VectorField length = new VectorField(_field, FieldAnalysis.VFLength, 1, false); this.AddScalar(length[0] as ScalarField); } // Remove length texture? else if (effect != RenderEffect.LIC_LENGTH && Effect == RenderEffect.LIC_LENGTH && _field != null) { ShaderResourceView[] cpy = _fieldTextures; _fieldTextures = new ShaderResourceView[cpy.Length - 1]; Array.Copy(cpy, _fieldTextures, _fieldTextures.Length); } switch (effect) { case RenderEffect.LIC: case RenderEffect.LIC_LENGTH: //Debug.Assert(_fields.Length >= 2); this._technique = _planeEffect.GetTechniqueByName("RenderLIC" + _fieldTextures.Length); break; case RenderEffect.CHECKERBOARD: this._technique = _planeEffect.GetTechniqueByName("RenderChecker"); break; case RenderEffect.CHECKERBOARD_COLORMAP: this._technique = _planeEffect.GetTechniqueByName("RenderCheckerTex" + _fieldTextures.Length); break; case RenderEffect.OVERLAY: this._technique = _planeEffect.GetTechniqueByName("Overlay" + _fieldTextures.Length); break; case RenderEffect.LAPLACE: this._technique = _planeEffect.GetTechniqueByName("Laplace" + _fieldTextures.Length); break; case RenderEffect.GRADIENT: this._technique = _planeEffect.GetTechniqueByName("Gradient" + _fieldTextures.Length); break; case RenderEffect.COLORMAP: default: this._technique = _planeEffect.GetTechniqueByName("RenderTex" + _fieldTextures.Length); break; } Effect = effect; }
public VectorField GetTimeSlice(int slice) { ScalarField[] slices = new ScalarField[Scalars.Length]; for (int scalar = 0; scalar < Scalars.Length; ++scalar) { slices[scalar] = _scalarsUnsteady[scalar].GetTimeSlice(slice); } var result = new VectorField(slices); result.TimeSlice = slice; result.InvalidValue = InvalidValue; return(result); }
public static Integrator CreateIntegrator(VectorField field, Type type, Line core = null, float force = 0.1f) { switch (type) { case Type.RUNGE_KUTTA_4: return(new IntegratorRK4(field)); case Type.REPELLING_RUNGE_KUTTA: return(new IntegratorRK4Repelling(field, core, force)); default: return(new IntegratorEuler(field)); } }
public static void TestCP() { Random rnd = new Random(DateTime.Today.Millisecond); RectlinearGrid grid = new RectlinearGrid(new Index(2, 2)); ScalarField cell0 = new ScalarField(grid); ScalarField cell1 = new ScalarField(grid); for (int tests = 0; tests < 100; ++tests) { for (int i = 0; i < 4; ++i) { cell0.Data[i] = (float)rnd.NextDouble() - 0.5f; cell1.Data[i] = (float)rnd.NextDouble() - 0.5f; } VectorField cell = new VectorField(new ScalarField[] { cell0, cell1 }); //PointSet<Point> points = FieldAnalysis.ComputeCriticalPointsRegularAnalytical2D(cell); } }
public VectorField(VectorField field, VFJFunction function, int outputDim, bool needJacobian = true) { int scalars = outputDim;/*function(field.Sample(0), field.SampleDerivative(new Vector(0, field.Size.Length))).Length;*/ _scalars = new ScalarField[scalars]; FieldGrid gridCopy = field.Grid.Copy(); // In case the input field was time dependant, this one is not. Still, we keep the size and origin of the time as new dimension! gridCopy.TimeDependant = false; for (int dim = 0; dim < scalars; ++dim) { Scalars[dim] = new ScalarField(gridCopy); } this.InvalidValue = field.InvalidValue; GridIndex indexIterator = new GridIndex(field.Size); foreach (GridIndex index in indexIterator) { Vector v = field.Sample((int)index); if (v[0] == InvalidValue) { for (int dim = 0; dim < Scalars.Length; ++dim) { Scalars[dim][(int)index] = (float)InvalidValue; } continue; } SquareMatrix J = needJacobian? field.SampleDerivative(index) : null; Vector funcValue = function(v, J); for (int dim = 0; dim < Scalars.Length; ++dim) { var vec = Scalars[dim]; Scalars[dim][(int)index] = funcValue[dim]; } } }
protected void ComputeOkubo(float[] radii, float[] angles, out Graph2D[] okuboData) { float integrationLength = 40; // IntegrationTime; // ~~~~~~~~~~~~~~~~~~ Initialize seed points. ~~~~~~~~~~~~~~~~~~~~ \\ PointSet <Point> circle = new PointSet <Point>(new Point[radii.Length * angles.Length * 4]); okuboData = new Graph2D[angles.Length]; if (_velocity.TimeOrigin > SliceTimeMain || _velocity.TimeOrigin + _velocity.Size.T < SliceTimeMain) { LoadField(SliceTimeMain, MemberMain, 1); } VectorField okuboField = new VectorField(_velocity.GetSlice(SliceTimeMain), FieldAnalysis.OkuboWeiss, 1); float mean, fill, standardDeviation; (okuboField.Scalars[0] as ScalarField).ComputeStatistics(out fill, out mean, out _standardDeviation); Console.WriteLine("Mean: " + mean + ", SD: " + _standardDeviation + ", valid cells: " + fill); for (int angle = 0; angle < angles.Length; ++angle) { okuboData[angle] = new Graph2D(radii.Length); for (int rad = 0; rad < radii.Length; ++rad) { okuboData[angle].X[rad] = radii[rad]; float x = (float)(Math.Sin(angles[angle] + Math.PI / 2)); float y = (float)(Math.Cos(angles[angle] + Math.PI / 2)); Vec2 pos = new Vec2(_selection.X + x * radii[rad], _selection.Y + y * radii[rad]); if (!okuboField.Grid.InGrid(pos) || !okuboField.IsValid(pos)) { okuboData[angle].Fx[rad] = 1; continue; } okuboData[angle].Fx[rad] = okuboField[0].Sample(pos) + 0.2f * _standardDeviation; } } }
/// <summary> /// Plane to display scalar/vector field data on. Condition: Fields domain is 2D. /// </summary> /// <param name="origin"></param> /// <param name="xAxis"></param> /// <param name="yAxis"></param> /// <param name="scale">Scaling the field extent.</param> /// <param name="field"></param> public FieldPlane(Plane plane, VectorField fields, RenderEffect effect = RenderEffect.DEFAULT, Colormap map = Colormap.Parula) { #if DEBUG // Assert that the fields are 2 dimensional. foreach (Field field in fields.Scalars) { System.Diagnostics.Debug.Assert(field.Size.Length >= 2); } #endif this._effect = _planeEffect; this._vertexSizeBytes = 32; this._numVertices = 6; this.UsedMap = map; this._width = fields[0].Size[0]; this._height = fields[0].Size[1]; this._invalid = fields.InvalidValue ?? float.MaxValue; this._field = fields; // Setting up the vertex buffer. GenerateGeometry(plane, fields[0].Size.ToInt2(), fields.TimeSlice ?? 0); // Generating Textures from the fields. _fieldTextures = new ShaderResourceView[fields.Scalars.Length]; for (int f = 0; f < _field.NumVectorDimensions; ++f) { Texture2D tex = ColorMapping.GenerateTextureFromField(_device, fields[f]); _fieldTextures[f] = new ShaderResourceView(_device, tex); } this.SetRenderEffect(effect); this._vertexLayout = new InputLayout(_device, _technique.GetPassByIndex(0).Description.Signature, new[] { new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0), new InputElement("TEXTURE", 0, Format.R32G32B32A32_Float, 16, 0) }); }
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> 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> 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 IntegratorRK4Repelling(VectorField field, Line core, float outwardForce) : base(field) { Core = core; Force = outwardForce; }
public IntegratorRK4(VectorField field) : base(field) { }
public IntegratorEuler(VectorField field) { Field = field; }