Exemple #1
0
        public void ArcLength()
        {
            double radius = 50;
            double angle  = 50;

            Assert.Equal(43.633231299858238, CircleHelper.ArcLength(radius, angle));
        }
Exemple #2
0
        public void ChordLength()
        {
            double radius = 50;
            double angle  = 50;

            Assert.Equal(42.26182617407, System.Math.Round(CircleHelper.ChordLength(radius, angle), 12));
        }
Exemple #3
0
        public void ArcLengthRound12()
        {
            double radius = 50;
            double angle  = 50;

            Assert.Equal(43.633231299858, System.Math.Round(CircleHelper.ArcLength(radius, angle), 12));
        }
Exemple #4
0
        private void BuildRings()
        {
            detailCount = 40;
            ringClrs    = new int[] { Color.Red.ToArgb(), Color.Green.ToArgb(), Color.Blue.ToArgb() };
            vBuffer     = new VertexBuffer(typeof(CustomVertex.PositionColored), (detailCount + 1) * 3,
                                           gDevice, Usage.WriteOnly, CustomVertex.PositionColored.Format,
                                           Pool.Managed);
            CustomVertex.PositionColored[] verts = (CustomVertex.PositionColored[])vBuffer.Lock(0, LockFlags.None);

            Vector2[] points;
            CircleHelper.CalcCirclePointsCCW(detailCount + 1, 1, new Vector2(), out points);
            BuildRingOnX(verts, (detailCount + 1) * 0, ringClrs[0], points);
            BuildRingOnY(verts, (detailCount + 1) * 1, ringClrs[1], points);
            BuildRingOnZ(verts, (detailCount + 1) * 2, ringClrs[2], points);

            vBuffer.Unlock();
        }
Exemple #5
0
    /// <summary>
    /// Rotates the current active object.
    /// </summary>
    private void Rotate()
    {
        // only rotate if the current frame is not skipped
        currentPauseFrames--;
        if (currentPauseFrames > 0 || Vector3.Distance(lastPos, GetHandPos()) > maxMovementPerFrame)
        {
            return;
        }
        currentPauseFrames = pauseFrames;

        // save the current hand position
        lastHandPositions.Add(GetHandPos());

        // get current hand velocity
        float velocity = GetHandVelocity();

        // rotate a object around a primary axis if there are enough past hand positions
        if (lastHandPositions.Count > (rotationTrailSize / 3) * 3)
        {
            // ensure that the number of past hand position does not exceed the rotationTrailSize
            lastHandPositions.RemoveAt(0);

            // don't rotate if hand is to slow
            if (velocity < minVelocityForRotation)
            {
                return;
            }

            // calculate the average normal vector of the last triples
            Vector3 normal = GetAverageNormalVector(lastHandPositions);

            // check if the angle between the average normal vector and a primary axis is smaller than the given treshould
            Vector3 rotationAxis = Vector3.zero;
            if (Vector3.Angle(Vector3.forward, normal) <= fixAxisAngleThreshold)
            {
                rotationAxis = Vector3.forward;
            }
            else if (Vector3.Angle(Vector3.back, normal) <= fixAxisAngleThreshold)
            {
                rotationAxis = Vector3.back;
            }
            else if (Vector3.Angle(Vector3.right, normal) <= fixAxisAngleThreshold)
            {
                rotationAxis = Vector3.right;
            }
            else if (Vector3.Angle(Vector3.left, normal) <= fixAxisAngleThreshold)
            {
                rotationAxis = Vector3.left;
            }
            else if (Vector3.Angle(Vector3.up, normal) <= fixAxisAngleThreshold)
            {
                rotationAxis = Vector3.up;
            }
            else if (Vector3.Angle(Vector3.down, normal) <= fixAxisAngleThreshold)
            {
                rotationAxis = Vector3.down;
            }

            // rotate object around the detected primary axis (if there is one)
            if (rotationAxis != Vector3.zero)
            {
                // determine the circle described by the hand movements
                Vector2 v1 = lastHandPositions[lastHandPositions.Count - 3].ToVector2(rotationAxis);
                Vector2 v2 = lastHandPositions[lastHandPositions.Count - 2].ToVector2(rotationAxis);
                Vector2 v3 = lastHandPositions[lastHandPositions.Count - 1].ToVector2(rotationAxis);
                CircleHelper.FindCircle(v1, v2, v3, out Vector2 center, out float radius);

                // calculate the moved angle
                Vector2 c_v2  = v2 - center;
                Vector2 c_v3  = v3 - center;
                float   angle = Vector2.Angle(c_v2, c_v3);

                if (!float.IsNaN(angle))
                {
                    float factor;
                    // linearly increase rotation amount for the first velocity window
                    if (velocity < midVelocityForRotation)
                    {
                        factor = minLoops + ((velocity - minVelocityForRotation) /
                                             (midVelocityForRotation - minVelocityForRotation)) * (midLoops - minLoops);
                    }
                    // exponentially increase rotation amount for the second velocity window
                    else
                    {
                        float cmVelocity = (velocity - midVelocityForRotation) * 100;
                        factor = Mathf.Max(midMaxLoops - cmVelocity * cmVelocity * 0.0005f, maxLoops);
                    }

                    // don't rotate if jitter is detected
                    if (angle > maxAngle && GetTrackingConfidence() > minConfidence)
                    {
                        return;
                    }

                    angle = angle / factor;

                    currentTakeable.transform.RotateAround(currentTakeable.transform.position, rotationAxis, angle);

                    ManageRotationLever(rotationAxis, angle);
                }
            }
        }
    }
        private AlgorithmManager()
        {
            // Color c = Colors.

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Graham Scan modified", "Rod Stephens", "Slowest but simple and great for comparison.",
                                                  OxyPlot.OxyColors.DarkKhaki,
                                                  (points, algorithmStat) =>
            {
                var stopwatch = Stopwatch.StartNew();
                var result    = RodStephens.Geometry.MakeConvexHull(points);
                stopwatch.Stop();

                if (algorithmStat != null)
                {
                    algorithmStat.TimeSpanOriginal = stopwatch.Elapsed;
                }
                return(result.ToArray());
            }));

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Monotone chain", "A. M. Andrew, David Piepgrass (Qwerties)", "Very slow. Got on the web.",
                                                  OxyPlot.OxyColors.Chocolate,
                                                  (points, algorithmStat) =>
            {
                var stopwatch = Stopwatch.StartNew();
                var result    = MonotoneChainImplementation.ComputeConvexHull(points);
                stopwatch.Stop();

                if (algorithmStat != null)
                {
                    algorithmStat.TimeSpanOriginal = stopwatch.Elapsed;
                }
                return(result.ToArray());
            }));

            AlgoIndexMonotoneChain = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Heap", "?, Pat Morin", "Very slow. Got on the web.", OxyPlot.OxyColors.Thistle,
                                                  (points, algorithmStat) =>
            {
                ConvexHullHeapAndChanWrapper wrapper = new ConvexHullHeapAndChanWrapper(points);
                wrapper.HeapHull();
                var result = wrapper.HullPoints;

                if (algorithmStat != null)
                {
                    algorithmStat.TimeSpanOriginal = wrapper.TimeSpan;
                }

                return(result);
            }));

            AlgoIndexHeap = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "MI ConvexHUll (Delaunay/Voronoi)", "Delaunay and Voronoi, davecz",
                                                  "Slow. From CodePlex. Could do 3D.", OxyPlot.OxyColors.Indigo,
                                                  (points, algorithmStat) =>
            {
                var vertices = new Vertex[points.Length];
                int i        = 0;
                foreach (var point in points)
                {
                    vertices[i] = new Vertex(point.X, point.Y);
                    i++;
                }

                var stopwatch  = Stopwatch.StartNew();
                var convexHull = MIConvexHull.ConvexHull.Create(vertices);
                stopwatch.Stop();

                var hullPoints = new Point[convexHull.Points.Count()];
                i = 0;

                if (hullPoints.Length > 0)
                {
                    var firstFace = convexHull.Faces.First();
                    var face      = firstFace;
                    do
                    {
                        hullPoints[i++] = new Point(face.Vertices[0].Position[0], face.Vertices[0].Position[1]);

                        face = face.Adjacency[0];
                    } while (face != firstFace);
                }

                if (algorithmStat != null)
                {
                    algorithmStat.TimeSpanOriginal = stopwatch.Elapsed;
                }

                return(hullPoints);
            }));

            AlgoIndexMiConvexHull = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Chan", "Chan, Pat Morin", "C code. Has a little bug (happen rarely). Got on the web.",
                                                  OxyPlot.OxyColors.Red,
                                                  (points, algorithmStat) =>
            {
                Point[] result = null;
                try
                {
                    ConvexHullHeapAndChanWrapper wrapper = new ConvexHullHeapAndChanWrapper(points);
                    wrapper.ChanHull();
                    result = wrapper.HullPoints;

                    if (algorithmStat != null)
                    {
                        algorithmStat.TimeSpanOriginal = wrapper.TimeSpan;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                    Debugger.Break();
                }

                return(result);
            }));

            AlgoIndexChan = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "LiuAndChen", "Liu and Chen, Eric Ouellet", "The same as Ouellet without my optimization",
                                                  OxyPlot.OxyColors.LightSkyBlue,
                                                  (points, algorithmStat) =>
            {
                LiuAndChen.ConvexHull convexHull = new LiuAndChen.ConvexHull(points);
                convexHull.CalcConvexHull(LiuAndChen.ConvexHullThreadUsage.OnlyOne);
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexLiuAndChen = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# ST", "Eric Ouellet, Eric Ouellet", "Highly tested.", OxyPlot.OxyColors.Green,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHull.ConvexHull convexHull = new OuelletConvexHull.ConvexHull(points);
                convexHull.CalcConvexHull(ConvexHullThreadUsage.OnlyOne);
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullSingleThread = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# ST (array copy)", "Eric Ouellet, Eric Ouellet", "Array instead of a List.",
                                                  OxyPlot.OxyColors.Purple,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHullArray.ConvexHull convexHull = new OuelletConvexHullArray.ConvexHull(OuelletConvexHullArray.PointArrayManipulationType.ArrayCopy, points);
                convexHull.CalcConvexHull(OuelletConvexHullArray.ConvexHullThreadUsage.OnlyOne);
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullSingleThreadArray = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# ST (array C memcpy)", "Eric Ouellet, Eric Ouellet", "Array instead of a List.",
                                                  OxyPlot.OxyColors.HotPink,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHullArray.ConvexHull convexHull =
                    new OuelletConvexHullArray.ConvexHull(OuelletConvexHullArray.PointArrayManipulationType.UnsafeCMemCopy, points);
                convexHull.CalcConvexHull(OuelletConvexHullArray.ConvexHullThreadUsage.OnlyOne);
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullSingleThreadArrayMemCpy = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# ST (array copy immu)", "Eric Ouellet, Eric Ouellet", "Array instead of a List.",
                                                  OxyPlot.OxyColors.Olive,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHullArray.ConvexHull convexHull =
                    new OuelletConvexHullArray.ConvexHull(OuelletConvexHullArray.PointArrayManipulationType.ArrayCopyImmutable, points);
                convexHull.CalcConvexHull(OuelletConvexHullArray.ConvexHullThreadUsage.OnlyOne);
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullSingleThreadArrayImmu = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# ST (array memcpy no indirect)", "Eric Ouellet, Eric Ouellet",
                                                  "Array instead of a List.", OxyPlot.OxyColors.Gold,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHullArrayNoIndirect.ConvexHull convexHull =
                    new OuelletConvexHullArrayNoIndirect.ConvexHull(OuelletConvexHullArrayNoIndirect.PointArrayManipulationType.ArrayCopyImmutable, points);
                convexHull.CalcConvexHull(OuelletConvexHullArrayNoIndirect.ConvexHullThreadUsage.OnlyOne);
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullSingleThreadArrayMemCpyNoIndirect = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# Avl", "Eric Ouellet, Eric Ouellet",
                                                  "Same as ST but with Avl Tree instead of List.", OxyPlot.OxyColors.Orange,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHullAvl.ConvexHullAvl convexHull = new OuelletConvexHullAvl.ConvexHullAvl(points);
                convexHull.CalcConvexHull(OuelletConvexHullAvl.ConvexHullThreadUsageAvl.OnlyOne);
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullAvl = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# Avl v2", "Eric Ouellet, Eric Ouellet", "Same as AVL with some optimisation.",
                                                  OxyPlot.OxyColors.Blue,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHullAvl2.ConvexHullAvl convexHull = new OuelletConvexHullAvl2.ConvexHullAvl(points);
                convexHull.CalcConvexHull();
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullAvl2 = _algorithms.Count - 1;

            // Color c = Colors.
            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# Avl v3 (standard/batch)",
                                                  "Eric Ouellet, Eric Ouellet", "Based on Avl v2 with little modifications and additional online methods.", OxyPlot.OxyColors.DarkCyan,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHullAvl3.ConvexHull convexHull = new OuelletConvexHullAvl3.ConvexHull();
                convexHull.CalcConvexHull(points);
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullAvl2Online = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# Avl v3 (one by one in a loop)", "Eric Ouellet, Eric Ouellet",
                                                  "Based on Avl v2 with little modifications and additional online methods.", OxyPlot.OxyColors.DarkOrchid,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHullAvl3.ConvexHull convexHull = new OuelletConvexHullAvl3.ConvexHull();

                // TEST to ensure that IsHullPoint and DynamicallyAddAnotherPointToConvexHullIfAppropriate appears to be coherent and works fine.
                //foreach (Point pt in points)
                //{
                //	Point[] ptsBefore = convexHullOnline.GetResultsAsArrayOfPoint();
                //	int countBefore = convexHullOnline.Count;
                //	int t = convexHullOnline.IsHullPoint(pt);
                //	int r = convexHullOnline.DynamicallyAddAnotherPointToConvexHullIfAppropriate(pt);
                //	Point[] ptsAfter = convexHullOnline.GetResultsAsArrayOfPoint();

                //	Debug.Assert(t == r);

                //	DifferencesInPath diffs = ConvexHullUtil.GetPathDifferences("", points, ptsAfter, ptsBefore);
                //	if (r == 1)
                //	{
                //		Debug.Assert(diffs.HasErrors);
                //	}
                //	else
                //	{
                //		Debug.Assert(! diffs.HasErrors);
                //	}
                //}

                foreach (Point pt in points)
                {
                    convexHull.TryAddOnePoint(pt);
                }

                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullAvl2OnlineWithOnlineUse = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# 4T", "Eric Ouellet, Eric Ouellet", "1 thread per quadrant for part 2",
                                                  OxyPlot.OxyColors.SlateBlue,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHull.ConvexHull convexHull = new OuelletConvexHull.ConvexHull(points);
                convexHull.CalcConvexHull(ConvexHullThreadUsage.FixedFour);
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHull4Threads = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# MT", "Eric Ouellet, Eric Ouellet",
                                                  "All thread part 1, 4 threads part 2, 1 thread part 3", OxyPlot.OxyColors.SaddleBrown,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHull.ConvexHull convexHull = new OuelletConvexHull.ConvexHull(points);
                convexHull.CalcConvexHull(ConvexHullThreadUsage.All);
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullMultiThreads = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet CPP ST", "Eric Ouellet, Eric Ouellet", " thread, highly optimized, very ugly code",
                                                  OxyPlot.OxyColors.YellowGreen,
                                                  (points, algorithmStat) =>
            {
                double elapsedTime = 0;

                OuelletConvexHullCpp convexHull = new OuelletConvexHullCpp();
                var result = convexHull.OuelletHullManagedWithElapsedTime(points, true, ref elapsedTime);

                if (algorithmStat != null)
                {
                    algorithmStat.TimeSpanOriginal = TimeSpanHelper.MoreAccurateTimeSpanFromSeconds(elapsedTime);
                }

                return(result);
            }));

            AlgoIndexOuelletConvexHullCpp = _algorithms.Count - 1;

            // Color r = Colors.CornflowerBlue;
            _algorithms.Add(new AlgorithmOnline(AlgorithmType.ConvexHullOnline, "Ouellet C# Avl v3 (** Only for Online performance test)", "Eric Ouellet, Eric Ouellet",
                                                "Add point one by one for 'merging' performance test only.", OxyPlot.OxyColors.CornflowerBlue, () =>
            {
                return(new OuelletConvexHullAvl3.ConvexHull());
            },

                                                (Object obj, Point pt, AlgorithmStat stat) =>
            {
                var convexHullOnline = obj as OuelletConvexHullAvl3.ConvexHull;
                if (convexHullOnline == null)
                {
                    throw new ArgumentException($"argument obj: '{obj}' is invalid.");
                }

                Stopwatch stopwatch        = Stopwatch.StartNew();
                EnumConvexHullPoint result = convexHullOnline.TryAddOnePoint(pt);
                stopwatch.Stop();

                stat.TimeSpanCSharp = stat.TimeSpanCSharp.Add(stopwatch.Elapsed);

                return(result == EnumConvexHullPoint.ConvexHullPoint);
            },

                                                (Object obj) =>
            {
                var ch = obj as OuelletConvexHullAvl3.ConvexHull;
                if (ch == null)
                {
                    throw new ArgumentException($"argument obj: '{obj}' is invalid.");
                }
                return(ch.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullAvl2OnlineWithOnlineInterface = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.SmallestEnclosingCircle, "Smallest Enclosing Circle", "Rod Stephens, Rod Stephens",
                                                  "Slow Slow Slow. Select max 500 pts.", OxyPlot.OxyColors.Red,
                                                  (points, algorithmStat) =>
            {
                var stopwatch = Stopwatch.StartNew();

                Point center  = new Point(0, 0);
                double radius = 0;
                SmallestEnclosingCircle.FindMinimalBoundingCircle(points, out center, out radius);

                stopwatch.Stop();

                if (algorithmStat != null)
                {
                    algorithmStat.TimeSpanCSharp = stopwatch.Elapsed;
                }

                Point[] result = CircleHelper.CreateCircleWithPoints(center, radius, 200);                         // 200 seems ok :-)

                return(result);
            }));

            AlgoIndexSmallestEnclosingCircle = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.SmallestEnclosingCircle, "Smallest Enclosing Circle from ConvexHull (Ouellet ST)",
                                                  "Rod Stephens, Rod Stephens", "Same algo as previous but points are first filtered by the Convex Hull algo", OxyPlot.OxyColors.Blue,
                                                  (points, algorithmStat) =>
            {
                var stopwatch = Stopwatch.StartNew();


                ConvexHull convexHull = new ConvexHull(points);
                convexHull.CalcConvexHull(ConvexHullThreadUsage.OnlyOne);
                Point[] hullPoints = convexHull.GetResultsAsArrayOfPoint();


                Point center  = new Point(0, 0);
                double radius = 0;
                SmallestEnclosingCircle.FindMinimalBoundingCircle(hullPoints, out center, out radius);

                stopwatch.Stop();

                if (algorithmStat != null)
                {
                    algorithmStat.TimeSpanCSharp = stopwatch.Elapsed;
                }

                Point[] result = CircleHelper.CreateCircleWithPoints(center, radius, 200);                         // 200 seems ok :-)

                return(result);
            }));

            AlgoIndexSmallestEnclosingCircle = _algorithms.Count - 1;
        }
Exemple #7
0
        public void Circumference()
        {
            double radius = 50;

            Assert.Equal(314.15926535897933, CircleHelper.Circumference(radius));
        }
Exemple #8
0
        public void Area()
        {
            double radius = 50;

            Assert.Equal(7853.981633974483, CircleHelper.Area(radius));
        }