Ejemplo n.º 1
0
 public static void WriteGraphCSV(string file, Graph2D graph)
 {
     try {
         // Open the file. If it already exists, overwrite.
         using (FileStream fs = File.Open(@file, FileMode.Create))
         {
             using (StreamWriter writer = new StreamWriter(fs))
             {
                 foreach (float f in graph.X)
                 {
                     writer.Write("{0},", f);
                 }
                 writer.Write('\n');
                 foreach (float f in graph.Fx)
                 {
                     if (!float.IsNaN(f))
                     {
                         writer.Write("{0},", f);
                     }
                 }
                 writer.Write('\n');
             }
         }
     }
     catch (Exception e)
     {
         Console.WriteLine(e.Message);
     }
 }
Ejemplo n.º 2
0
        public static void WriteGraphCSV(string file, Graph2D graph)
        {
            try {
                // Open the file. If it already exists, overwrite.
                using (FileStream fs = File.Open(@file, FileMode.Create))
                {
                    using (StreamWriter writer = new StreamWriter(fs))
                    {
                        foreach (float f in graph.X)
                        {
                            writer.Write("{0},", f);
                        }
                        writer.Write('\n');
                        foreach (float f in graph.Fx)
                        {
                            if (!float.IsNaN(f))
                                writer.Write("{0},", f);
                        }
                        writer.Write('\n');

                    }
                }
            }
            catch(Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
 public Graph2D(Graph2D cpy)
 {
     _x = new float[cpy.Length];
     _fx = new float[cpy.Length];
     Array.Copy(cpy._x, _x, cpy.Length);
     Array.Copy(cpy._fx, _fx, cpy.Length);
 }
Ejemplo n.º 5
0
        public static void ReadFromFile(string file, out Graph2D[] lines)
        {
            // Open the file.
            using (FileStream fs = File.Open(@file, FileMode.Open))
            {
                using (BinaryReader reader = new BinaryReader(fs))
                {
                    // Read number of lines.
                    lines = new Graph2D[reader.ReadInt32()];

                    // Read line lengths in order.
                    for (int l = 0; l < lines.Length; ++l)
                    {
                        lines[l] = new Graph2D(reader.ReadInt32());// { Positions = new Vector3[reader.ReadInt32()] };
                    }
                    // Read positions.
                    foreach (Graph2D line in lines)
                    {
                        for (int v = 0; v < line.Length; ++v)
                        {
                            line.X[v]  = reader.ReadSingle();
                            line.Fx[v] = reader.ReadSingle();
                        }
                    }
                }
            }
        }
Ejemplo n.º 6
0
 public Graph2D(Graph2D cpy)
 {
     _x  = new float[cpy.Length];
     _fx = new float[cpy.Length];
     Array.Copy(cpy._x, _x, cpy.Length);
     Array.Copy(cpy._fx, _fx, cpy.Length);
 }
Ejemplo n.º 7
0
        public static void WriteGraphCSV(string file, Graph2D[] graph)
        {
            try {
                // Open the file. If it already exists, overwrite.
                using (FileStream fs = File.Open(@file, FileMode.Create))
                {
                    using (StreamWriter writer = new StreamWriter(fs))
                    {
                        // X values in first row. Assume equal.
                        foreach (float f in graph[0].X)
                        {
                            writer.Write("{0},", f);
                        }
                        writer.Write('\n');

                        // Fx values subsequent.
                        foreach (Graph2D g in graph)
                        {

                            foreach (float f in g.Fx)
                            {
                                writer.Write("{0},", f);
                            }
                            writer.Write('\n');
                        }
                    }
                }
            }
            catch(Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
Ejemplo n.º 8
0
        protected static Graph2D OperateBackwards(Graph2D g0, Graph2D g1, ValueOperator func)
        {
            if (g0.Length == 0 || g1.Length == 0)
            {
                return(new Graph2D(new float[0], new float[0])
                {
                    Offset = 0
                });
            }
            float[] x  = new float[g0.Length + g1.Length];
            float[] fx = new float[x.Length];

            int p0 = 0; int p1 = 0; int pCount = 0;

            if (g0.X[0] > g1.X[0])
            {
                p0 = g0.GetLastBelowX(g1.X[0]) + 1;
            }
            if (g1.X[0] > g0.X[0])
            {
                p1 = g1.GetLastBelowX(g0.X[0]) + 1;
            }

            float maxX = Math.Min(g0.X[g0.Length - 1], g1.X[g1.Length - 1]);

            // Interleave
            while (p0 < g0.Length && p1 < g1.Length)
            {
                float v0 = p0 < g0.Length ? g0.X[p0] : float.MaxValue;
                float v1 = p1 < g1.Length ? g1.X[p1] : float.MaxValue;

                if (v0 > v1)
                {
                    x[pCount]  = v0;
                    fx[pCount] = func(g1.Sample(v0), g0.Fx[p0]);
                    p0++;
                }
                if (v0 < v1)
                {
                    x[pCount]  = v1;
                    fx[pCount] = func(g1.Fx[p1], g0.Sample(v1));
                    p1++;
                }
                if (v0 == v1)
                {
                    x[pCount]  = v0;
                    fx[pCount] = func(g1.Fx[p1], g0.Fx[p0]);
                    p0++; p1++;
                }

                ++pCount;
            }
            if (pCount < x.Length)
            {
                Array.Resize(ref x, pCount);
                Array.Resize(ref fx, pCount);
            }
            return(new Graph2D(x, fx));
        }
Ejemplo n.º 9
0
 public static Graph2D Distance(Graph2D a, Graph2D b, bool forward = true)
 {
     if (forward)
     {
         return(Operate(a, b, (x, y) => ((x - y) * (x - y))));
     }
     return(OperateBackwards(a, b, (x, y) => ((x - y) * (x - y))));
 }
Ejemplo n.º 10
0
        public static Graph2D operator *(Graph2D g, float f)
        {
            Graph2D result = new Graph2D(g);

            for (int x = 0; x < result.Fx.Length; ++x)
            {
                result.Fx[x] *= f;
            }

            return(result);
        }
Ejemplo n.º 11
0
        public static Graph2D DistanceCutSmooth(Graph2D a, Graph2D b, bool forward = true)
        {
            Graph2D diff;

            if (forward)
            {
                diff = Operate(a, b, (x, y) => ((x - y) * (x - y)));
            }
            else
            {
                diff = OperateBackwards(a, b, (x, y) => ((x - y) * (x - y)));
            }
            float minXjump = -1;

            for (int ax = 0; ax < a.Length - 1; ++ax)
            {
                if ((forward && a.X[ax] > a.X[ax + 1]) ||
                    (!forward && a.X[ax] < a.X[ax + 1]))
                {
                    minXjump = a.X[ax];
                    break;
                }
            }

            for (int bx = 0; bx < b.Length - 1 && b.X[bx] < minXjump; ++bx)
            {
                if ((forward && b.X[bx] > b.X[bx + 1]) ||
                    (!forward && b.X[bx] < b.X[bx + 1]))
                {
                    minXjump = b.X[bx];
                    break;
                }
            }

            if (minXjump > 0)
            {
                //int jumpPos = diff.GetLastBelowX(minXjump);
                diff.CutGraph(minXjump);
                diff = new Graph2D(new float[0], new float[0]);
            }

            return(diff);
        }
Ejemplo n.º 12
0
        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;
                }
            }
        }
Ejemplo n.º 13
0
        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);
        }
Ejemplo n.º 14
0
        public static Graph2D DistanceCutSmooth(Graph2D a, Graph2D b, bool forward = true)
        {
            Graph2D diff;
            if (forward)
                diff =  Operate(a, b, (x, y) => ((x - y) * (x - y)));
            else
                diff = OperateBackwards(a, b, (x, y) => ((x - y) * (x - y)));
            float minXjump = -1;
            for(int ax = 0; ax < a.Length - 1; ++ax)
            {
                if((forward && a.X[ax] > a.X[ax+1]) ||
                  (!forward && a.X[ax] < a.X[ax+1]))
                {
                    minXjump = a.X[ax];
                    break;
                }
            }

            for (int bx = 0; bx < b.Length - 1 && b.X[bx] < minXjump; ++bx)
            {
                if ((forward && b.X[bx] > b.X[bx + 1]) ||
                   (!forward && b.X[bx] < b.X[bx + 1]))
                {
                    minXjump = b.X[bx];
                    break;
                }
            }

            if(minXjump > 0)
            {
                //int jumpPos = diff.GetLastBelowX(minXjump);
                diff.CutGraph(minXjump);
                diff = new Graph2D(new float[0], new float[0]);
            }

            return diff;
        }
Ejemplo n.º 15
0
 public static Graph2D Distance(Graph2D a, Graph2D b, bool forward = true)
 {
     if(forward)
         return Operate(a, b, (x, y) => ((x - y) * (x - y)));
     return OperateBackwards(a, b, (x, y) => ((x - y) * (x - y)));
 }
Ejemplo n.º 16
0
        protected static Graph2D OperateBackwards(Graph2D g0, Graph2D g1, ValueOperator func)
        {
            if (g0.Length == 0 || g1.Length == 0)
            {
                return new Graph2D(new float[0], new float[0]) { Offset = 0 };
            }
            float[] x = new float[g0.Length + g1.Length];
            float[] fx = new float[x.Length];

            int p0 = 0; int p1 = 0; int pCount = 0;
            if (g0.X[0] > g1.X[0])
            {
                p0 = g0.GetLastBelowX(g1.X[0]) + 1;
            }
            if (g1.X[0] > g0.X[0])
            {
                p1 = g1.GetLastBelowX(g0.X[0]) + 1;
            }

            float maxX = Math.Min(g0.X[g0.Length - 1], g1.X[g1.Length - 1]);
            // Interleave
            while (p0 < g0.Length && p1 < g1.Length)
            {
                float v0 = p0 < g0.Length ? g0.X[p0] : float.MaxValue;
                float v1 = p1 < g1.Length ? g1.X[p1] : float.MaxValue;

                if (v0 > v1)
                {
                    x[pCount] = v0;
                    fx[pCount] = func(g1.Sample(v0), g0.Fx[p0]);
                    p0++;
                }
                if (v0 < v1)
                {
                    x[pCount] = v1;
                    fx[pCount] = func(g1.Fx[p1], g0.Sample(v1));
                    p1++;
                }
                if (v0 == v1)
                {
                    x[pCount] = v0;
                    fx[pCount] = func(g1.Fx[p1], g0.Fx[p0]);
                    p0++; p1++;
                }

                ++pCount;
            }
            if (pCount < x.Length)
            {
                Array.Resize(ref x, pCount);
                Array.Resize(ref fx, pCount);
            }
            return new Graph2D(x, fx);
        }
Ejemplo n.º 17
0
        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;
        }
Ejemplo n.º 18
0
        public List <Renderable> EditorMap()
        {
            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;

            // Recompute lines if necessary.
            if (numLines > 0 && (
                    _lastSetting == null ||
                    NumLinesChanged ||
                    OffsetRadiusChanged ||
                    _selectionChanged ||
                    SliceTimeMainChanged ||
                    DiffusionMeasureChanged))
            {
                switch (DiffusionMeasure)
                {
                case RedSea.DiffusionMeasure.FTLE:
                    _currentFileName = "FTLE";
                    _rangeGraphData  = 0.095f;
                    break;

                case RedSea.DiffusionMeasure.Direction:
                    _currentFileName = "Okubo";
                    _rangeGraphData  = 0.2f;
                    break;

                default:
                    _currentFileName = "Concentric";
                    _rangeGraphData  = 20;
                    break;
                }

                _graph = null;
                // Load computed data.
                if (LoadGraph(_currentFileName, out _dataGraph))
                {
                    // Is there a drawing saved? If not, make a new empty graph.
                    if (!LoadGraph(_currentFileName + "Selection", _selectedCore, out _selectionData, out _selectionLines))
                    {
                        if (_selectionData == null || _selectionData.Length != _dataGraph.Length)
                        {
                            _selectionData = new Graph2D[_dataGraph.Length];
                        }

                        for (int angle = 0; angle < _selectionData.Length; ++angle)
                        {
                            _selectionData[angle] = new Graph2D(_dataGraph[angle].Length);
                            for (int rad = 0; rad < _selectionData[angle].Length; ++rad)
                            {
                                _selectionData[angle].X[rad]  = _dataGraph[angle].X[rad];
                                _selectionData[angle].Fx[rad] = 0;
                            }
                        }

                        //_selectionLines = FieldAnalysis.WriteGraphToSun(_selectionData, new Vector3(_selection.X, _selection.Y, SliceTimeMain));
                    }

                    // Some weird things happening, maybe this solves offset drawing...
                    _graphData = FieldAnalysis.WriteGraphToSun(_dataGraph, new Vector3(_selection.X, _selection.Y, SliceTimeMain));


                    var dataRange = _graphData.GetRange(2);
                    //_rangeGraphData = dataRange.Item2 - SliceTimeMain;
                    _minGraphData = SliceTimeMain;

                    MaskOnData();
                }

                _selectionChanged = false;
                rebuilt           = true;
            }

            // Add the lineball.
            if (_pathlines != null)
            {
                renderables.Add(_pathlines);
            }
            if (_graph != null) // && !Graph && !Flat)
            {
                renderables.Add(_graph);
            }
            //if (_selectionGraph != null && (Graph || Flat))
            //    renderables.Add(_selectionGraph);
            if (_boundaryBallSpacetime != null && !Graph)// && Graph && !Flat)
            {
                renderables.Add(_boundaryBallSpacetime);
            }
            if (SliceTimeMain != SliceTimeReference)
            {
                renderables.Add(_compareSlice);
            }
            if (_boundaryCloud != null)// && Graph)
            {
                renderables.Add(_boundaryCloud);
            }
            if (_specialObject != null)
            {
                renderables.Add(_specialObject);
            }
            if (_selectedCore >= 0 && _coreBall != null && !Flat)
            {
                renderables.Add(_coreBall);
            }

            return(renderables);
        }
Ejemplo n.º 19
0
        //protected Line IntegrateCircle(float angle, float radius, out Graph2D graph, float time = 0)
        //{
        //}
        protected LineSet IntegrateCircles(float[] radii, float[] angles, out Graph2D[] graph, int time = 0)
        {
            // ~~~~~~~~~~~~~~~~~~ Initialize seed points. ~~~~~~~~~~~~~~~~~~~~ \\
            PointSet<Point> circle = new PointSet<Point>(new Point[radii.Length * angles.Length]);
            for (int a = 0; a < angles.Length; ++a)
            {
                float x = (float)(Math.Sin(angles[a] + Math.PI / 2));
                float y = (float)(Math.Cos(angles[a] + Math.PI / 2));

                for (int r = 0; r < radii.Length; ++r)
                {
                    // Take the selection as center.
                    circle[a*radii.Length + r] = new Point() { Position = new Vector3(_selection.X + x * radii[r], _selection.Y + y * radii[r], time) };
                }
            }

            // ~~~~~~~~~~~~ Integrate Pathlines and Adapt ~~~~~~~~~~~~~~~~~~~~~~~~ \\
            // Setup integrator.
            Integrator pathlineIntegrator = Integrator.CreateIntegrator(null, IntegrationType, _cores[_selectedCore], _repulsion);
            pathlineIntegrator.StepSize = StepSize;
            LineSet pathlines;

            // Count out the runs for debugging.
            int run = 0;

            // ~~~~~~~~~~~~ Integrate Pathlines  ~~~~~~~~~~~~~~~~~~~~~~~~ \\
            #region IntegratePathlines
            // Do we need to load a field first?
            if (_velocity.TimeOrigin > time || _velocity.TimeOrigin + _velocity.Size.T < time)
                LoadField(time, MemberMain);

            // Integrate first few steps.
            pathlineIntegrator.Field = _velocity;
            pathlines = pathlineIntegrator.Integrate(circle, false)[0];

            // Append integrated lines of next loaded vectorfield time slices.
            float timeLength = STEPS_IN_MEMORY * 3 - 2/*RedSea.Singleton.NumSubstepsTotal / _everyNthTimestep / 4*/ + time;
            while (_currentEndStep + 1 < timeLength)
            {
                // Don't load more steps than we need to!
                int numSteps = (int)Math.Min(timeLength - _currentEndStep, STEPS_IN_MEMORY);
                pathlineIntegrator.Field = null;
                LoadField(_currentEndStep, MemberMain, numSteps);

                // Integrate further.
                pathlineIntegrator.Field = _velocity;
                pathlineIntegrator.IntegrateFurther(pathlines);
            }
            #endregion IntegratePathlines

            // ~~~~~~~~~~~~ Get Boundary ~~~~~~~~~~~~~~~~~~~~~~~~ \\
            #region GetBoundary
            // The two needes functions.
            //Line[] distances = FieldAnalysis.GetGraph(_cores[_selectedCore], _selection, pathlines, (StepSize * _everyNthTimestep) / 24.0f, _everyNthTimestep, true);
            //Line[] angles = FieldAnalysis.GetGraph(_cores[_selectedCore], _selection, pathlines, (StepSize * _everyNthTimestep) / 24.0f, _everyNthTimestep, false);
            graph = FieldAnalysis.GetDistanceToAngle(_cores[_selectedCore], _selection, pathlines);
            //graph[0].CutGraph((float)(Math.PI * 2));
            //Array.Resize(ref pathlines[0].Positions, graph[0].Length);
            FieldAnalysis.WriteXToLinesetAttribute(pathlines, graph);

            #endregion GetBoundary
            //LineSet[] subsets = new LineSet[angles.Length];
            //for(int s = 0; s < subsets.Length; ++ s)
            //{
            //    subsets[s] = new LineSet(pathlines, s * radii.Length, radii.Length);
            //}
            //return subsets;
            return pathlines;

            //            LineSet set = new LineSet(_coreAngleGraph);
            //GeometryWriter.WriteHeightCSV(RedSea.Singleton.DonutFileName + "Angle.csv", set);
            //            GeometryWriter.WriteToFile(RedSea.Singleton.DonutFileName + ".angle", set);

            //            set = new LineSet(_coreDistanceGraph);
            //GeometryWriter.WriteHeightCSV(RedSea.Singleton.DonutFileName + "Distance.csv", set);
            //            GeometryWriter.WriteToFile(RedSea.Singleton.DonutFileName + ".distance", set);
        }
Ejemplo n.º 20
0
        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];
        }
Ejemplo n.º 21
0
        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);
        }