RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1441371
Accepted
FotonPC
FotonPC
Asked:2022-08-21 22:49:04 +0000 UTC2022-08-21 22:49:04 +0000 UTC 2022-08-21 22:49:04 +0000 UTC

自己的 3D 引擎 Python 一个线段和一个矩形的交集

  • 772

我正在用 Python 编写自己的小型 3D 引擎。我使用了一种技术,您可以从相机拍摄大量光线像素并测量到三角形的距离。但是,即使经过 numpy、优化和 numba 并行化等等,即使在 400 + 400 像素的分辨率下,1000 个三角形的正常对象也会渲染 4-7 分钟,这已经很多了。

有一个新算法的想法 - 你看看相机中从拍摄点到三角形点的片段落在哪个像素上,找到三个像素并使用 pygame 在它们之间制作一个三角形。

但是在互联网上,我没有找到关于如何计算至少一个线段和一个矩形在空间中的交点的明确解释。请帮忙,因为我什至没有完成学业自己想出一个垫子。解决方案。

CPU 和 Windows 的理想解决方案

图片 - 对要完成的方法的描述 在此处输入图像描述

python 3d
  • 1 1 个回答
  • 47 Views

1 个回答

  • Voted
  1. Best Answer
    FotonPC
    2022-08-22T21:51:15Z2022-08-22T21:51:15Z

    我没有等待答案,所以我解决了几个小时的方程式,一切都解决了。这是此功能的代码。也许你可以在之前以某种方式优化 numpy

    import numba as nb
    import numpy as np
    import time
    import math
    import random
    
    
    @nb.njit(cache=True, fastmath=True)
    def _3points_to_eq_of_plane(_3v3):
        v3_1 = _3v3[0]
        v3_2 = _3v3[1]
        v3_3 = _3v3[2]
        x1 = v3_1[0]
        y1 = v3_1[1]
        z1 = v3_1[2]
        x2 = v3_2[0]
        y2 = v3_2[1]
        z2 = v3_2[2]
        x3 = v3_3[0]
        y3 = v3_3[1]
        z3 = v3_3[2]
        vector1 = np.array([x2 - x1, y2 - y1, z2 - z1])
        vector2 = np.array([x3 - x1, y3 - y1, z3 - z1])
    
        cross_product = [vector1[1] * vector2[2] - vector1[2] * vector2[1],
                         -1 * (vector1[0] * vector2[2] - vector1[2] * vector2[0]),
                         vector1[0] * vector2[1] - vector1[1] * vector2[0]]
    
        a = cross_product[0]
        b = cross_product[1]
        c = cross_product[2]
        d = - (cross_product[0] * x1 + cross_product[1] * y1 + cross_product[2] * z1)
        return np.array([a, b, c, d])
    
    
    @nb.njit(cache=True, fastmath=True)
    def xyz_of_intersection_plane_and_line(a, b, c, d, x1, x2, y1, y2, z1, z2):
        x21 = (x2 - x1)
        y21 = (y2 - y1)
        z21 = (z2 - z1)
        zxy21_c = (z21 + x21) * c / y21
        y = (y1 * zxy21_c - z1 * c - d - x1 * a) / (zxy21_c + b)
        x = (y - y1) * x21 / y21 + x1
        z = (-d - a * x - b * y) / c
        return np.array([x, y, z])
    
    @nb.njit(cache=True, fastmath=True)
    def point_to_pix_on_rect(view_rect, v3, size_x, size_y):
        xsx = (view_rect[1][0] - view_rect[0][0]) / (size_x - 1)
        xsy = (view_rect[1][1] - view_rect[0][1]) / (size_x - 1)
        xsz = (view_rect[1][2] - view_rect[0][2]) / (size_x - 1)
        ysx = (view_rect[3][0] - view_rect[0][0]) / (size_y - 1)
        ysy = (view_rect[3][1] - view_rect[0][1]) / (size_y - 1)
        ysz = (view_rect[3][2] - view_rect[0][2]) / (size_y - 1)
        c1x = view_rect[0][0]
        c1y = view_rect[0][1]
        c1z = view_rect[0][2]
        x = v3[0]
        y = v3[1]
        z = v3[2]
        # Здесь система из 3 линейный уравнений с 2 неизвестными
        # Выбираем лучшие - самая большая разница координат для меньшей ошибки
        dx = abs(view_rect[2][0] - view_rect[0][0])
        dy = abs(view_rect[2][1] - view_rect[0][1])
        dz = abs(view_rect[2][2] - view_rect[0][2])
        if ysx == 0 and ysz == 0:
            i = (x - c1x) / xsx
            j = (y - c1y) / ysy
        elif ysy == 0 and ysz == 0:
            i = (x - c1x) / ysx
            j = (y - c1y) / xsx
        elif ysy == 0 and ysx == 0:
            i = (x - c1x) / ysz
            j = (y - c1y) / ysz
        elif min(dx, dy, dz) == dx:
            # i * xsx + j * ysx = x - c1x
            # i * xsy + j * ysy = y - c1y
            print(ysx)
            i = (y - c1y + x * ysy / ysx + c1x * ysy / ysx) / (xsy - xsx * ysy / ysx)
            j = (x - c1x - i * xsx) / ysx
    
        elif min(dx, dy, dz) == dy:
            # i * xsx + j * ysx = x - c1x
            # i * xsz + j * ysz = z - c1z
    
            i = (z - c1z + x * ysz / ysx + c1x * ysz / ysx) / (xsz - xsx * ysz / ysx)
            j = (x - c1x - i * xsx) / ysx
    
        elif min(dx, dy, dz) == dz:
            # i * xsz + j * ysz = z - c1z
            # i * xsy + j * ysy = y - c1y
    
            i = (y - c1y + z * ysy / ysz + c1z * ysy / ysz) / (xsy - xsz * ysy / ysz)
            j = (y - c1y - i * xsy) / ysy
        return np.array([i, j])
    
    @nb.njit(cache=True, fastmath=True)
    def rect_view_triangle_size_to_pix(rect, view, triangle, size_x, size_y):
        points_from_rect = np.zeros((3, 3))
        points_from_rect[0] = rect[0]
        points_from_rect[1] = rect[1]
        points_from_rect[2] = rect[2]
        plane = _3points_to_eq_of_plane(points_from_rect)
        a = plane[0]
        b = plane[1]
        c = plane[2]
        d = plane[3]
        v31 = triangle[0]
        v32 = triangle[1]
        v33 = triangle[2]
        x = view[0]
        y = view[1]
        z = view[2]
        x1 = v31[0]
        y1 = v31[1]
        z1 = v31[2]
        x2 = v32[0]
        y2 = v32[1]
        z2 = v32[2]
        x3 = v33[0]
        y3 = v33[1]
        z3 = v33[2]
        v31 = xyz_of_intersection_plane_and_line(a, b, c, d, x, x1, y, y1, z, z1)
        v32 = xyz_of_intersection_plane_and_line(a, b, c, d, x, x2, y, y2, z, z2)
        v33 = xyz_of_intersection_plane_and_line(a, b, c, d, x, x3, y, y3, z, z3)
        v1 = point_to_pix_on_rect(rect, v31, size_x, size_y)
        v2 = point_to_pix_on_rect(rect, v32, size_x, size_y)
        v3 = point_to_pix_on_rect(rect, v33, size_x, size_y)
        ret = np.zeros((3, 2))
        ret[0] = v1
        ret[1] = v2
        ret[2] = v3
        return ret
    
    
    @nb.njit(cache=True, fastmath=True, parallel=True)
    def get_triangles_on_screen(triangles, rect, size_x, size_y, x, y, z):
        view = np.zeros(3)
        view[0] = x
        view[1] = y
        view[2] = z
        lt = len(triangles)
        result = np.zeros((lt, 3, 2))
        for i in nb.prange(lt):
            result[i] = rect_view_triangle_size_to_pix(rect, view, triangles[i], size_x, size_y)
        return result
    

    剩下的我就不给你看了。图片用 470,000 个多边形渲染半秒。triangles - 三角形数组 rect - 矩形 size_x - 窗口宽度 size_y - 窗口高度 x、y、z - 相机位置

    在此处输入图像描述

    • 1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5