有没有更有效的方法来纹理圆?

2024-01-18

我正在尝试创建一个随机生成的“行星”(圆圈),并且我希望水、土地和树叶的面积由柏林噪声或类似的东西决定。目前我有这个(伪)代码:

for (int radius = 0; radius < circleRadius; radius++) {
    for (float theta = 0; theta < TWO_PI; theta += 0.1) {
        float x = radius * cosine(theta);
        float y = radius * sine(theta);
        int colour = whateverFunctionIMake(x, y);
        setPixel(x, y, colour);
    }
}

这不仅不起作用(由于精度问题,圆圈中存在“间隙”),而且速度非常慢。即使我通过将增量更改为 0.01 来提高分辨率,它仍然会丢失像素,并且速度甚至更慢(我在使用 Java 的普通计算机上获得 10fps(我不知道最好的),增量为 0.01。这当然是不可接受的对于一场比赛)。

我怎样才能获得类似的结果,同时计算成本要低得多?

提前致谢。


为什么不使用:

(x-x0)^2 + (y-y0)^2 <= r^2

这么简单:

int x0=?,y0=?,r=?; // your planet position and size
int x,y,xx,rr,col;
for (rr=r*r,x=-r;x<=r;x++)
 for (xx=x*x,y=-r;y<=r;y++)
  if (xx+(y*y)<=rr)
   {
   col = whateverFunctionIMake(x, y);
   setPixel(x0+x, y0+y, col);   
   }

全部为整数,没有浮动或慢速操作,没有间隙...不要忘记使用 randseed 进行着色函数...

[编辑1]更多的东西

现在,如果您想要速度,则需要直接像素访问(在大多数平台中,Pixels、SetPixel、PutPixels 等都很慢。因为它们执行很多操作,例如范围检查、颜色转换等...)如果您获得直接像素访问或渲染到您自己的数组/图像中,无论您需要添加屏幕剪辑(因此您不需要检查每个像素上的像素是否在屏幕内),以避免在您的圆圈与屏幕重叠时发生访问冲突。

正如评论中提到的,你可以摆脱x*x and y*y使用先前值的内部循环(因为两者x,y仅递增)。有关它的更多信息请参阅:

  • 16T 中的 32 位 SQRT,无乘法 https://stackoverflow.com/a/34657972/2521214

数学是这样的:

(x+1)^2 = (x+1)*(x+1) = x^2 + 2x + 1

所以而不是xx = x*x我们只是做xx+=x+x+1尚未增加x or xx+=x+x-1 if x已经增加了。

当把所有这些放在一起时,我得到了这个:

void circle(int x,int y,int r,DWORD c)
    {
    // my Pixel access
    int **Pixels=Main->pyx;         // Pixels[y][x]
    int   xs=Main->xs;              // resolution
    int   ys=Main->ys;
    // circle
    int sx,sy,sx0,sx1,sy0,sy1;      // [screen]
    int cx,cy,cx0,    cy0    ;      // [circle]
    int rr=r*r,cxx,cyy,cxx0,cyy0;   // [circle^2]
    // BBOX + screen clip
    sx0=x-r; if (sx0>=xs) return; if (sx0<  0) sx0=0;
    sy0=y-r; if (sy0>=ys) return; if (sy0<  0) sy0=0;
    sx1=x+r; if (sx1<  0) return; if (sx1>=xs) sx1=xs-1;
    sy1=y+r; if (sy1<  0) return; if (sy1>=ys) sy1=ys-1;
    cx0=sx0-x; cxx0=cx0*cx0;
    cy0=sy0-y; cyy0=cy0*cy0;
    // render
    for (cxx=cxx0,cx=cx0,sx=sx0;sx<=sx1;sx++,cxx+=cx,cx++,cxx+=cx)
     for (cyy=cyy0,cy=cy0,sy=sy0;sy<=sy1;sy++,cyy+=cy,cy++,cyy+=cy)
      if (cxx+cyy<=rr)
       Pixels[sy][sx]=c;
    }

这会渲染一个具有半径的圆512 px in ~35ms so 23.5 Mpx/s填充我的设置(AMD A8-5500 3.2GHz Win7 64位单线程VCL/GDI 32位应用程序由BDS2006 C++编码)。只需更改对您使用的样式/api 的直接像素访问...

[Edit2]

要测量 x86/x64 上的速度,您可以使用RDTSC这里的 asm 指令是我很久以前使用过的一些古老的 C++ 代码(在没有本机 64 位内容的 32 位环境中):

double _rdtsc()
    {
    LARGE_INTEGER x; // unsigned 64bit integer variable from windows.h I think
    DWORD l,h;       // standard unsigned 32 bit variables
    asm {
        rdtsc
        mov l,eax
        mov h,edx
        }
    x.LowPart=l;
    x.HighPart=h;
    return double(x.QuadPart);
    }

它返回 CPU 自加电以来所经过的时钟。请注意,您应该考虑溢出,因为在快速机器上,32 位计数器在几秒钟内就会溢出。此外,每个核心都有单独的计数器,因此请设置与单个 CPU 的关联性。在测量变速时钟之前,通过一些计算加热 CPU,并转换为时间,只需除以 CPU 时钟频率。要获得它,只需执行以下操作:

t0=_rdtsc()
sleep(250);
t1=_rdtsc();
fcpu = (t1-t0)*4;

和测量:

t0=_rdtsc()
mesured stuff
t1=_rdtsc();
time = (t1-t0)/fcpu

if t1<t0你溢出了,你需要添加一个常量到结果或再次测量。此外,测量过程的时间必须小于溢出周期。为了提高精度,请忽略操作系统粒度。欲了解更多信息,请参阅:

  • 测量缓存延迟 https://stackoverflow.com/a/21548494/2521214
  • 您系统上的缓存大小估算? https://stackoverflow.com/a/21509808/2521214设置亲和力示例
  • 使用背靠背 rdtsc 进行负时钟周期测量? https://stackoverflow.com/a/21572772/2521214
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有没有更有效的方法来纹理圆? 的相关文章

  • 每个面有 K 个顶点的 3D 点的三角测量

    我正在使用 Three js 我有一个收藏3D点 x y z 和面的集合 一张脸是由K points 它可以是凸的 也可以是凹的 我在 Three js 文档中找不到任何可以帮助我的内容 一种解决方案可能是对这些形状进行三角测量 但到目前为
  • 如何计算贝塞尔曲线的面积?

    给定以下描述 SVG 三次贝塞尔曲线的路径 例如 M 300 140 C 300 40 500 40 500 140 并假设有一条直线连接端点300 140 to 500 140 封闭曲线下的面积 是否可以计算如此封闭的面积 谁能建议一个公
  • SVG 圆起点

    如何更改 svg 圆的起始点 使其从 0 点钟开始逐渐动画化 默认圆形 svg 从 3 点钟开始 我当前的圈子 悬停动画 timeline position fixed width 500px height 500px top 50 lef
  • MongoDB 如何查找哪个多边形包含指定点?

    我将许多多边形插入MongoDB 2 4 8 并希望找到指定点所在的多边形 这似乎是一个常见问题 但在阅读了谷歌的所有文档后 我没有得到结果 所以提出这个问题 e g db addr poly insert loc type Polygon
  • 如何在给定角度的椭圆轮廓上获取点?

    因此 我给出了椭圆 它们由中点 水平半径 rh 和垂直半径 rv 定义 我使用 sin cos 绘制它们 结果对我来说看起来相当不错 只是确保这不是错误源 现在假设我有一个给定的角度 或方向向量 并且我希望椭圆轮廓上的点具有该角度 方向 我
  • 计算 3D(或 n 维)质心的最佳方法是什么?

    作为工作项目的一部分 我必须计算 3D 空间中一组点的质心 现在我正在以一种看似简单但天真的方式来做这件事 通过取每组点的平均值 如下所示 centroid average x average y average z where x y a
  • 在jframe中创建java的正方形,矩形,三角形[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一个 Java 问题 据我了解 无法在 Java 中绘制几何图形 代码和以下内容您可以帮助我吗 这是代码 public class
  • 连接无序线段

    我的算法生成一个 通常 数千条线段 全是二维 的列表 我需要将它们连接成大型折线 这些生成的折线可能是闭合的或开放的 但它们永远不会自相交 线段没有方向 即可能需要翻转线段才能将其连接到相邻线段 找到这些折线的极快方法是什么 我必须实时执行
  • 查找一对 QuadCurve2D 的交集

    有没有一种简单的方法来近似两个实例的点 如果有 QuadCurve2D相交 也就是说 我如何计算图中红点的坐标 没有明显的方法QuadCurve2D去做这个 注意 这些点并不准确 因为我已经为图表手动调整了它们 另请注意 缺失 的第四个点
  • 在 boost 几何体中创建实心多边形

    我是增强几何的新手 我已经创建了多边形boost geometry assign points 但我只创建该多边形的外部和内部是空的 所以我尝试测试boost geometry overlaps 两个多边形 A B 且 A 在 B 内部 结
  • 如何检测重叠的圆圈并相应地填充颜色?

    我使用 3 个数组 用于 x y 和半径大小 创建了 5 个具有随机 x 和 y 坐标和半径的圆 但是 我需要圆圈根据它们是否与另一个圆圈重叠来动态改变颜色 因此 如果 5 个圆圈之一根本不重叠 则应将其涂成黑色 重叠的圆圈应为青色 如果两
  • 确定线段是否与多边形相交

    如果我在 2D 平面上有一个向量 由 2 个点组成的线 我如何确定它是否穿过多边形 我知道我可以采用构成多边形的每条线并查看是否有相交 但有更好的方法吗 我读过这篇文章如何确定 2D 点是否在多边形内 https stackoverflow
  • 三角形未在 OSX 上的 OpenGL 2.1 中绘制

    我正在学习有关使用 OpenGL 在 Java 中创建游戏引擎的教程 我正在尝试在屏幕上渲染一个三角形 一切运行良好 我可以更改背景颜色 但三角形不会显示 我还尝试运行作为教程系列的一部分提供的代码 但它仍然不起作用 教程链接 http b
  • 为什么 Point 和 Rectangle 不能用作可选参数?

    我试图将一个可选参数传递给一个几何函数 称为offset 可能会或可能不会指定 但 C 不允许我执行以下任何操作 有办法做到这一点吗 默认为空 错误 类型的值无法用作默认参数 因为没有到 System Drawing Point 类型的标准
  • 在iOS开发中,使用Core Graphics和/或Quartz 2D,如何绘制一个充满渐变的圆,使其看起来像一个球体?

    到目前为止 我已经研究过使用 CGContextDrawLinearGradient 和 CGContextDrawRadialGradient 但是 对于前者 我无法弄清楚如何使渐变看起来像球体 对于后者 我无法弄清楚如何使渐变成球体形状
  • 以有效的方式找到最近点

    我在 2d 平面上有一个点 例如 x0 y0 和一组 n 点 x1 y1 xn yn 我想在 a 中找到距离 x0 y0 最近的点比尝试所有要点要好得多 有什么解决办法吗 我还应该说我的观点是这样排序的 bool less point a
  • 如何将多个矩形打包为 2d 盒子俄罗斯方块样式

    我有许多不同宽度和高度的矩形 我有一个更大的矩形平台来放置它们 我想将它们包装在平台的一侧 以便它们在纵向 X 尺寸上展开 但将横向 Y 尺寸保持在最小限度 就是把它们像俄罗斯方块游戏一样放置 不能有重叠 但可以有间隙 有没有算法可以做到这
  • 查找二维空间中圆内的所有点

    我表示我的 2D 空间 考虑一个窗口 其中每个像素显示为 2D 数组中的一个单元格 即 100x100 的窗口由相同维度的数组表示 现在给定窗口中的一个点 如果我画一个半径的圆r 我想找到该圆圈中的所有点 我想我应该检查半径周围方形区域中的
  • 使用 boost 几何检查两条线是否有交点

    是否可以使用 boost geometry 检查两条线段 每条线段由二维中的两个点给出 是否彼此相交 如果可能的话 boost geometry 是否还允许检查特殊情况 例如另一条线上只有一个点 数字上 或者两条线相等 如果你具体谈论Boo
  • 合并空间上接近的路径/线段的算法

    我正在寻找一种用于街道地图制图概括的几何算法 名称 在我的地图数据中 我有许多路径 点的有序列表 由线段连接 这些路径彼此靠近且几乎平行 我如何 1 识别这些 相邻路径 即如何找到比某个阈值更接近的路径 以及 2 将它们合并成一条路径 即如

随机推荐