Permalink
Browse files

Initial solution with Shewchuk predicates

  • Loading branch information...
1 parent aad1c69 commit 22be54fc5d251d6176486417da3b5b0e6e9416d1 @govert committed Jun 19, 2012
Showing with 8,798 additions and 0 deletions.
  1. +10 −0 .gitignore
  2. +42 −0 RobustGeometry.NET.sln
  3. +6 −0 RobustGeometry.NET.vsmdi
  4. +100 −0 RobustGeometry.Test/FpuControl.Test/FpuControlTests.cs
  5. +118 −0 RobustGeometry.Test/FpuControl.Test/RoundingTests.cs
  6. +151 −0 RobustGeometry.Test/FpuControl/FpuControl.cs
  7. +13 −0 RobustGeometry.Test/FpuControl/FpuControlContext.cs
  8. +259 −0 RobustGeometry.Test/Predicates.Test/ExpansionTests.cs
  9. +87 −0 RobustGeometry.Test/Predicates.Test/GeometricPredicatesTests.cs
  10. +17 −0 RobustGeometry.Test/Predicates.Test/InCircleTests.cs
  11. +17 −0 RobustGeometry.Test/Predicates.Test/InSphereTests.cs
  12. +17 −0 RobustGeometry.Test/Predicates.Test/Orient2DTests.cs
  13. +682 −0 RobustGeometry.Test/Predicates.Test/Orient3DTests.cs
  14. +278 −0 RobustGeometry.Test/Predicates.Test/ProductTests.cs
  15. +124 −0 RobustGeometry.Test/Predicates.Test/SumTests.cs
  16. +35 −0 RobustGeometry.Test/Properties/AssemblyInfo.cs
  17. +84 −0 RobustGeometry.Test/RobustGeometry.Test.csproj
  18. +35 −0 RobustGeometry.Test/TriangulationTests.cs
  19. +35 −0 RobustGeometry.Test/Util.Test/RuntimeTests.cs
  20. +298 −0 RobustGeometry.Test/Util.Test/UtilTests.cs
  21. +323 −0 RobustGeometry.Test/Util/DoubleConverter.cs
  22. +48 −0 RobustGeometry.Test/Util/DoubleExtensions.cs
  23. +261 −0 RobustGeometry.Test/Util/ExpansionExtensions.cs
  24. +67 −0 RobustGeometry.Test/Util/RandomDouble.cs
  25. +12 −0 RobustGeometry.Wpf/HalfedgeUtils3D.cs
  26. +55 −0 RobustGeometry.Wpf/Properties/AssemblyInfo.cs
  27. +71 −0 RobustGeometry.Wpf/Properties/Resources.Designer.cs
  28. +117 −0 RobustGeometry.Wpf/Properties/Resources.resx
  29. +30 −0 RobustGeometry.Wpf/Properties/Settings.Designer.cs
  30. +7 −0 RobustGeometry.Wpf/Properties/Settings.settings
  31. +84 −0 RobustGeometry.Wpf/RobustGeometry.Wpf.csproj
  32. +17 −0 RobustGeometry.testsettings
  33. +10 −0 RobustGeometry/HalfedgeMesh/Edge.cs
  34. +10 −0 RobustGeometry/HalfedgeMesh/Face.cs
  35. +10 −0 RobustGeometry/HalfedgeMesh/Halfedge.cs
  36. +10 −0 RobustGeometry/HalfedgeMesh/Mesh.cs
  37. +10 −0 RobustGeometry/HalfedgeMesh/TriangleMesh.cs
  38. +10 −0 RobustGeometry/HalfedgeMesh/Vertex.cs
  39. +803 −0 RobustGeometry/Predicates/ExactArithmetic.cs
  40. +3,006 −0 RobustGeometry/Predicates/GeometricPredicates.cs
  41. +39 −0 RobustGeometry/Properties/AssemblyInfo.cs
  42. +62 −0 RobustGeometry/RobustGeometry.csproj
  43. +10 −0 RobustGeometry/Triangulation/DivideAndConquerDelaunay.cs
  44. +10 −0 RobustGeometry/Triangulation/IncrementalDelaunay.cs
  45. +654 −0 TestResults/Govert_GOVERT-LAPTOP 2012-06-19 23_54_02.trx
  46. BIN TestResults/Govert_GOVERT-LAPTOP 2012-06-19 23_54_02/Out/RobustGeometry.Test.pdb
  47. BIN TestResults/Govert_GOVERT-LAPTOP 2012-06-19 23_54_02/Out/RobustGeometry.dll
  48. BIN TestResults/Govert_GOVERT-LAPTOP 2012-06-19 23_54_02/Out/RobustGeometry.pdb
  49. BIN TestResults/Govert_GOVERT-LAPTOP 2012-06-19 23_54_02/Out/robustgeometry.test.dll
  50. +654 −0 TestResults/Govert_GOVERT-LAPTOP 2012-06-19 23_54_33.trx
  51. BIN TestResults/Govert_GOVERT-LAPTOP 2012-06-19 23_54_33/Out/RobustGeometry.Test.pdb
  52. BIN TestResults/Govert_GOVERT-LAPTOP 2012-06-19 23_54_33/Out/RobustGeometry.dll
  53. BIN TestResults/Govert_GOVERT-LAPTOP 2012-06-19 23_54_33/Out/RobustGeometry.pdb
  54. BIN TestResults/Govert_GOVERT-LAPTOP 2012-06-19 23_54_33/Out/robustgeometry.test.dll
View
@@ -0,0 +1,10 @@
+.DS_Store
+*.pidb
+*.userprefs
+*.user
+*.suo
+_Resharper*
+obj
+bin
+tests/test-results
+tests/TestResults/
View
@@ -0,0 +1,42 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9071AAAF-E3F3-4E98-86EF-41AF1BC4CABB}"
+ ProjectSection(SolutionItems) = preProject
+ References.txt = References.txt
+ RobustGeometry.NET.vsmdi = RobustGeometry.NET.vsmdi
+ RobustGeometry.testsettings = RobustGeometry.testsettings
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RobustGeometry", "RobustGeometry\RobustGeometry.csproj", "{41AA789F-BA8A-4E89-B336-F6913CAB8773}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RobustGeometry.Test", "RobustGeometry.Test\RobustGeometry.Test.csproj", "{E5A33FE2-7166-464A-9F27-4477BDC0FEA0}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RobustGeometry.Wpf", "RobustGeometry.Wpf\RobustGeometry.Wpf.csproj", "{620326F2-7602-424F-B5C6-0A204C9E274D}"
+EndProject
+Global
+ GlobalSection(TestCaseManagementSettings) = postSolution
+ CategoryFile = RobustGeometry.NET.vsmdi
+ EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {41AA789F-BA8A-4E89-B336-F6913CAB8773}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {41AA789F-BA8A-4E89-B336-F6913CAB8773}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {41AA789F-BA8A-4E89-B336-F6913CAB8773}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {41AA789F-BA8A-4E89-B336-F6913CAB8773}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E5A33FE2-7166-464A-9F27-4477BDC0FEA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E5A33FE2-7166-464A-9F27-4477BDC0FEA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E5A33FE2-7166-464A-9F27-4477BDC0FEA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E5A33FE2-7166-464A-9F27-4477BDC0FEA0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {620326F2-7602-424F-B5C6-0A204C9E274D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {620326F2-7602-424F-B5C6-0A204C9E274D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {620326F2-7602-424F-B5C6-0A204C9E274D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {620326F2-7602-424F-B5C6-0A204C9E274D}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
View
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TestLists xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
+ <TestList name="Lists of Tests" id="8c43106b-9dc1-4907-a29f-aa66a61bf5b6">
+ <RunConfiguration id="6fb5775f-49af-4916-a9af-3e633b7fa92f" name="RobustGeometry" storage="robustgeometry.testsettings" type="Microsoft.VisualStudio.TestTools.Common.TestRunConfiguration, Microsoft.VisualStudio.QualityTools.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+ </TestList>
+</TestLists>
@@ -0,0 +1,100 @@
+using System;
+using System.Diagnostics;
+using System.Text;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using RobustArithmetic.Test.Util;
+
+namespace RobustArithmetic.Test.FpuControl.Test
+{
+ [TestClass]
+ public class FpuControlTests
+ {
+
+ // This test 'fails' under 64-bit, since we can't really set the precision to Extended64bit!
+ [TestMethod]
+ public void TestMethod1()
+ {
+ double before = TestCalc();
+ Assert.AreEqual(0.0, before);
+
+ var oldState = new FpuControl.State(FpuControl.GetState());
+ var oldPc = oldState.PrecisionControl;
+ uint err = FpuControl.SetState((uint)FpuControl.PrecisionControl.Extended64Bits, FpuControl.Mask.PrecisionControl);
+ var newState = new FpuControl.State(FpuControl.GetState());
+ var newPc = newState.PrecisionControl;
+
+ double after = TestCalc();
+ Assert.AreEqual(0.5, after);
+
+ double afterSafe = TestCalcSafe();
+ Assert.AreEqual(0.0, afterSafe);
+
+ FpuControl.SetState((uint)oldState.PrecisionControl, FpuControl.Mask.PrecisionControl);
+
+ double reset = TestCalc();
+ Assert.AreEqual(0.0, reset);
+
+ }
+
+ public double TestCalc()
+ {
+ double a = DoubleConverter.FromFloatingPointBinaryString("11111111111111111111111111111111111111111111111111110.0");
+ double b = DoubleConverter.FromFloatingPointBinaryString("00000000000000000000000000000000000000000000000000000.1");
+
+ double result = a + b - a;
+ return result;
+ }
+
+ // Here we add an explicit cast, which ensures that (a + b) is evaluated to 64-bits before continuing
+ public double TestCalcSafe()
+ {
+ double a = DoubleConverter.FromFloatingPointBinaryString("11111111111111111111111111111111111111111111111111110.0");
+ double b = DoubleConverter.FromFloatingPointBinaryString("00000000000000000000000000000000000000000000000000000.1");
+
+ double result = (double)(a + b) - a;
+ return result;
+ }
+
+
+ [TestMethod]
+ public void TestPrecision64()
+ {
+ double a = DoubleConverter.FromFloatingPointBinaryString('1'.Repeat(52) + "0"); // 111....11110
+ double b = DoubleConverter.FromFloatingPointBinaryString("0.1"); // 000....00000.1
+ double expected64 = a;
+
+ FpuControl.SetState((uint)FpuControl.PrecisionControl.Extended64Bits, FpuControl.Mask.PrecisionControl);
+ double result64 = (double)(a + b);
+ Assert.AreEqual(expected64, result64);
+
+ double result64_b = (a + b) - a;
+ Assert.AreEqual(b, result64_b);
+
+ double result64_0 = ((double)(a + b)) - a;
+ Assert.AreNotEqual(b, result64_0);
+ Assert.AreEqual(0.0, result64_0);
+
+ }
+
+ [TestMethod]
+ public void TestPrecision53()
+ {
+ double a = DoubleConverter.FromFloatingPointBinaryString('1'.Repeat(52) + "0"); // 111....11110
+ double b = DoubleConverter.FromFloatingPointBinaryString("0.1"); // 000....00000.1
+ double expected53 = a;
+
+ FpuControl.SetState((uint)FpuControl.PrecisionControl.Double53Bits, FpuControl.Mask.PrecisionControl);
+ double result53 = (double)(a + b);
+ Assert.AreEqual(expected53, result53);
+
+ double result53_0 = (a + b) - a;
+ Assert.AreEqual(0.0, result53_0);
+
+ double result53_X = ((double)(a + b)) - a;
+ Assert.AreEqual(0.0, result53_X);
+
+ }
+ }
+}
@@ -0,0 +1,118 @@
+using System;
+using System.Diagnostics;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using RobustArithmetic.Test.Util;
+
+namespace RobustArithmetic.Test.FpuControl.Test
+{
+ [TestClass]
+ public class RoundingTests
+ {
+
+ /// <summary>
+ /// This test shows how double rounding means that explicit casting does not get around Fpu settings
+ /// </summary>
+ [TestMethod]
+ public void ShowDoubleRounding()
+ {
+ double a = DoubleConverter.FromFloatingPointBinaryString('1'.Repeat(52) + "0"); // 111....11110
+ double b = DoubleConverter.FromFloatingPointBinaryString("0.100000000001"); // 000....00000.100000000001
+ double expected53 = DoubleConverter.FromFloatingPointBinaryString('1'.Repeat(52) + "1"); // 111....11111
+ double expected64 = a;
+
+ // Set Fpu to 53-bit precision (the default)
+ FpuControl.SetState((uint)FpuControl.PrecisionControl.Double53Bits, FpuControl.Mask.PrecisionControl);
+
+ double result53 = a + b;
+ Assert.AreEqual(expected53, result53);
+
+ // Set Fpu to 64-bit precision (extended precision)
+ FpuControl.SetState((uint)FpuControl.PrecisionControl.Extended64Bits, FpuControl.Mask.PrecisionControl);
+ double result64 = (double)(a + b);
+ Assert.AreEqual(expected64, result64);
+
+ double result64_0 = (a + b) - a;
+ Assert.AreNotEqual(0.0, result64_0);
+ Assert.AreNotEqual(b, result64_0);
+ Assert.AreEqual(0.5, result64_0); // 000....00000.1
+
+ }
+
+ /// <summary>
+ /// This is the double-rounding example from Priest.
+ /// The test exhibits the double rounding problem, where a floating point calculation is wrong if it is
+ /// rounded to 80-bits in the FPU, and then rounded to 64-bits by storing.
+ /// We get a different result to when the calculation is just rounded to 64-bits (53-bit precision FPU mode)
+ ///
+ /* Priest:
+ For example, in IEEE 754 arithmetic rounded first to 64
+ and then to 53 significant bits, the sum of
+ 2^52 + 1 and .5 - 2^-54 rounds to 2^52 + 1.5,
+ which then rounds to 2^52 + 2 by the round-to-even rule for halfway cases.
+ The roundoff is then .5 + 2^-54, which is not representable in 53 bits.
+
+ */
+ /// </summary>
+ [TestMethod]
+ public void ShowDoubleRoundingPriest()
+ {
+ double a = Math.Pow(2.0, 52.0) + 1.0;
+ double b = 0.5 - Math.Pow(2.0, -54.0);
+ double expected53 = a;
+ double expected64 = a + 1.0; // Math.Pow(2.0, 52.0) + 2.0;
+
+ Debug.Print(DoubleConverter.ToFloatingPointBinaryString(a));
+ Debug.Print(DoubleConverter.ToFloatingPointBinaryString(b));
+ Debug.Print(DoubleConverter.ToFloatingPointBinaryString(expected53));
+ Debug.Print(DoubleConverter.ToFloatingPointBinaryString(expected64));
+
+ // Set Fpu to 53-bit precision (the default)
+ FpuControl.SetState((uint)FpuControl.PrecisionControl.Double53Bits, FpuControl.Mask.PrecisionControl);
+
+ double result53 = a + b;
+ Debug.Print(DoubleConverter.ToFloatingPointBinaryString(result53));
+ Assert.AreEqual(expected53, result53);
+
+ // Set Fpu to 64-bit precision (extended precision)
+ FpuControl.SetState((uint)FpuControl.PrecisionControl.Extended64Bits, FpuControl.Mask.PrecisionControl);
+ double result64 = (double)(a + b);
+ Debug.Print(DoubleConverter.ToFloatingPointBinaryString(result64));
+ Assert.AreEqual(expected64, result64);
+ }
+
+ // This test exhibits the double rounding problem, where a floating point calculation is wrong if it is
+ // rounded to 80-bits in the FPU, and then rounded to 64-bits by storing.
+ // We get a different result to when the calculation is just rounded to 64-bits (53-bit precision FPU mode)
+ [TestMethod]
+ public void ShowDoubleRoundingPriestExplicit()
+ {
+ double a = DoubleConverter.FromFloatingPointBinaryString("1" + '0'.Repeat(51) + "1"); // 100....00001 (53-bits wide)
+ double b = DoubleConverter.FromFloatingPointBinaryString("0.0" + '1'.Repeat(53)); // 0.0111...111 (53 1's)
+ double expected53 = a;
+ double expected64 = a + 1.0; // The point is that this is different to expceted53.
+
+ Debug.Print(DoubleConverter.ToFloatingPointBinaryString(a));
+ Debug.Print(DoubleConverter.ToFloatingPointBinaryString(b));
+ Debug.Print(DoubleConverter.ToFloatingPointBinaryString(expected53));
+ Debug.Print(DoubleConverter.ToFloatingPointBinaryString(expected64));
+
+ // Set Fpu to 53-bit precision (the default)
+ FpuControl.SetState((uint)FpuControl.PrecisionControl.Double53Bits, FpuControl.Mask.PrecisionControl);
+
+ double result53 = a + b;
+ Debug.Print(DoubleConverter.ToFloatingPointBinaryString(result53));
+ Assert.AreEqual(expected53, result53);
+
+ // Explicit rounding makes no difference here (since we're in Double53bits precision FPU mode)
+ result53 = (double)(a + b);
+ Debug.Print(DoubleConverter.ToFloatingPointBinaryString(result53));
+ Assert.AreEqual(expected53, result53);
+
+ // Set Fpu to 64-bit precision (extended precision)
+ FpuControl.SetState((uint)FpuControl.PrecisionControl.Extended64Bits, FpuControl.Mask.PrecisionControl);
+ double result64 = (double)(a + b);
+ Debug.Print(DoubleConverter.ToFloatingPointBinaryString(result64));
+ Assert.AreEqual(expected64, result64);
+ }
+ }
+}
Oops, something went wrong.

0 comments on commit 22be54f

Please sign in to comment.