当前位置: 首页 > 知识库问答 >
问题:

凸四边形区域实现的数值精度

万选
2023-03-14

我已经实现了一种方法来计算R3中的凸四边形面积。该方法工作得很好,但我在小数点后8位遇到了数值精度问题。看看这个方法:

internal static double GetTriangleArea(double ax, double ay, double az,
            double bx, double by, double bz,
            double cx, double cy, double cz
            )
        {
            /**
             * AB = B-A = (ux, uy, uz)
             * AC = C-A = (wx, wy, wz)
             * 
             * S = 0.5*sqrt{(uy*wz - uz*wy)² + (uz*wx - ux*wz)² + (ux*wy - uy*wx)²}
             * */

            var ux = bx - ax;
            var uy = by - ay;
            var uz = bz - az;

            var wx = cx - ax;
            var wy = cy - ay;
            var wz = cz - az;

            var t1 = uy*wz - uz*wy;
            var t2 = uz*wx - ux*wz;
            var t3 = ux*wy - uy*wx;
            var s = 0.5*Math.Sqrt(t1*t1 + t2*t2 + t3*t3);

            return s;
        }

        internal static double GetConvexQuadrilateralArea(double ax, double ay, double az,
            double bx, double by, double bz,
            double cx, double cy, double cz,
            double dx, double dy, double dz)
        {
            var triangle1 = GetTriangleArea(ax, ay, az, bx, by, bz, cx, cy, cz);
            var triangle2 = GetTriangleArea(ax, ay, az, cx, cy, cz, dx,dy,dz);

            return triangle1 + triangle2;
        }

这是测试:

[TestMethod]
        public void ParallelogramOfBaseBAndHeightHMustHaveAreaEqualToBTimesH()
        {
            var random = new Random(1);
            const double scale = 10000;
            for (var counter = 0; counter < 1000; counter++)
            {
                double baseLength = random.NextDouble() * scale;
                double height = random.NextDouble() * scale;

                double dx = random.NextDouble()*scale;

                var a = new[] { 0, 0, 0 };
                var b = new[] { baseLength, 0, 0 };
                var c = new[] { baseLength+dx, height, 0 };
                var d = new[] { 0F+dx, height, 0 };

                double expected = baseLength * height;

                var result = MathUtils.GetConvexQuadrilateralArea(a[0], a[1], a[2], b[0], b[1], b[2], c[0], c[1], c[2],
                    d[0], d[1], d[2]);

                Assert.AreEqual(expected, result, Epsilon*scale,
                    string.Format("sideA: {0}, height: {1}, dx: {2}", baseLength, height, dx));
            }
        }

此测试失败,并显示以下消息:预期差值不大于

我的问题是:有没有办法在仍然使用双精度数字的情况下提高我的实现的数字精度?

共有1个答案

陆敏学
2023-03-14

双打有52位分数。在十进制中,大约是15.7位数。您的数字在点的左侧有八个数字,因此您只能期望在点的右侧有七个数字是正确的-这只是由于表示,甚至没有考虑计算产生的任何累积误差。

所以,答案是:不,没有办法。你必须使用更精确的格式。

 类似资料:
  • 多边形精灵(Polygon Sprite) 也是一个精灵,同样是为了展示一个可以被控制的图像,但是和普通精灵的区别是,普通精灵在绘图处理中被分为了两个三角形,多边形精灵则是被分为了一系列三角形。 为什么要使用多边形精灵 提高性能! 要深入分析这个是如何提高性能的,会需要很多和像素填充率有关的技术术语。幸好本节是入门性质的文档,能让大家理解多边形精灵比普通精灵性能好就可以了,不用讨论特定宽高矩形绘制

  • Jason Davies图形着色并没有避免我得到具有相同颜色的邻居多边形。 四色定理: 我们知道: 四色贴图定理指出,如果将平面分割成连续区域,生成一个称为贴图的图形,那么为贴图的区域着色所需的颜色不超过四种,因此没有两个相邻区域具有相同的颜色。(维基百科) 以及: 第二,为了定理的目的,每个“国家”必须是一个简单连接的区域,或相邻的区域。[...] 因为[非毗连国家]的领土必须是同一颜色,所以四

  • 我已经试着让这段代码工作了一段时间,但我仍然不知道我做错了什么。(LWJGL-Java) 我曾尝试在网上查看其他人的代码,但我找不到任何重大区别。事实上,我学会了将OpenGL与C结合使用,所以我的大脑可能会被它卡住,这可能就是我找不到错误的原因。 这是init(调用一次) 这是渲染函数: 着色器: 顶点: Framgent公司:

  • void fl_xyline(int x, int y, int x1) void fl_xyline(int x, int y, int x1, int y2) void fl_xyline(int x, int y, int x1, int y2, int x3) 先画一条水平的线,再画一条垂直的线条,最后画一条水平线 void fl_yxline(int x, int y, int y1)

  • 本文向大家介绍数据结构中的区域四叉树,包括了数据结构中的区域四叉树的使用技巧和注意事项,需要的朋友参考一下 区域四叉树可用于通过将区域划分为四个相等的象限,子象限等,以二维方式表示空间分区,每个叶节点由对应于特定子区域的数据组成。树中的每个节点都与正好有四个子节点或没有子节点(叶节点)相关联。遵循这种分解策略的四叉树的高度(即细分子象限,直到并且除非子象限中有需要进一步完善的有趣数据为止)敏感并取

  • 我试图计算矢量PDF中每个文本图示符的精确边界框。 这包括跟踪CTM,绘制/定位PDF指令等。,但也计算字形空间中每个特定字形的边界(使用嵌入式字体中GLYF表中的信息)。 我意识到PDF字体描述符包括每个嵌入式字体的粗略边界框,但这是字体中所有字形的组合——即适合字体中所有字形的最小边界框。为了我的目的,我需要更精确的定位。 我的具体应用是从乐谱的矢量PDF中提取音乐语义。因此,一个很好的约束是