[图形学]在半球面上均匀采样和cos加权采样

一、简介

本文介绍了如何在半球表面上进行半球面均匀采样半球面cos加权采样采样。
给出了相关公式推导和python代码实现。

二、在半球上采样

0.预备知识

1).球面坐标系与笛卡尔坐标系

在半球面上采样时,常使用球面坐标系。先采样球面坐标系下的坐标参数 ( θ , ϕ ) (\theta,\phi) (θ,ϕ),然后转换为笛卡尔坐标系参数 ( x , y , z ) (x,y,z) (x,y,z)。两个坐标系下的参数示意图如下:

笛卡尔坐标系示意图:
笛卡尔坐标系示意图

球面坐标系示意图:
球面坐标系
球面坐标系转为笛卡尔坐标系的公式如下:
x = c o s ( ϕ ) × s i n ( θ ) y = c o s ( θ )                  z = s i n ( ϕ ) × s i n ( θ ) x = cos(\phi) \times sin(\theta) \\ y = cos(\theta) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \\ z = sin(\phi) \times sin(\theta) x=cos(ϕ)×sin(θ)y=cos(θ)                z=sin(ϕ)×sin(θ)
在单位球面坐标系上的立体角微元等于:
d ω = d A r 2 = d A \rm{d}\omega = \frac{\rm{d}A}{r^2}=\rm{d}A dω=r2dA=dA
在单位球面上的面积微元 d A \rm{d}A dA等于:
d A = r 2 × s i n ( θ ) d θ d ϕ = s i n ( θ ) d θ d ϕ \rm{d}A=r^2\times sin(\theta)\rm{d}\theta\rm{d}\phi=sin(\theta)\rm{d}\theta\rm{d}\phi dA=r2×sin(θ)dθdϕ=sin(θ)dθdϕ

2).逆变换采样

逆变换采样是伪随机数采样的一种基本方法,在已知任意概率分布函数(probability distribution function, PDF)累计分布函数(cumulative distribution function, CDF)时,可以从该PDF中生成随机样本。本文只简单介绍逆变换采样的步骤和示例,对其推导过程和原理不做过多介绍。

使用逆变换采样方法的步骤如下:
  • (1).根据已知的PDF函数 f ( x ) = y f(x)=y f(x)=y,计算对应的CDF函数 F ( X ) F(X) F(X)
  • (2).根据 CDF函数 F ( X ) F(X) F(X) 求出其反函数 F − 1 ( Y ) F^{-1}(Y) F1(Y)
  • (3).在[0,1]上均匀采样随机变量 u u u
  • (4).那么 F − 1 ( u ) F^{-1}(u) F1(u)即为满足PDF函数 f ( x ) = y f(x)=y f(x)=y的随机变量。
示例:

已知PDF函数为 f ( x ) = 1 2 ( x ) exp ⁡ ( − ( x ) ) , x ≥ 0 f(x)=\frac{1}{2\sqrt(x)}\exp(-\sqrt(x)), x\geq 0 f(x)=2( x)1exp(( x)),x0,求采样得到满足 f ( x ) f(x) f(x)分布的随机变量。

  • (1).PDF为 f ( x ) = 1 2 ( x ) exp ⁡ ( − ( x ) ) , x ≥ 0 f(x)=\frac{1}{2\sqrt(x)}\exp(-\sqrt(x)), x\geq 0 f(x)=2( x)1exp(( x)),x0,那么CDF为 F ( X ) = 1 − e x p ( − ( X ) ) F(X)=1-exp(-\sqrt(X)) F(X)=1exp(( X))
  • (2).CDF对应的逆函数为 F − 1 ( Y ) = ( l o g ( 1 − Y ) ) 2 F^{-1}(Y)=(log(1-Y))^2 F1(Y)=(log(1Y))2
  • (3).在[0,1]上均匀采样随机变量 u u u
  • (4).那么随机变量 x ′ = F − 1 ( u ) = ( l o g ( 1 − u ) ) 2 x'=F^{-1}(u)=(log(1-u))^2 x=F1(u)=(log(1u))2即满足目标PDF函数;

1.在半球面上均匀采样 uniform sample

对于半球面上的均匀采样,PDF应与微元面积成正比,那么对于 ϕ \phi ϕ θ \theta θ的累计密度函数应该为:
C D F ( ϕ ) = ∫ 0 ϕ ∫ 0 π / 2 s i n ( θ ) d θ d ϕ ∫ 0 2 π ∫ 0 π / 2 s i n ( θ ) d θ d ϕ = ∫ 0 ϕ ∫ 0 π / 2 s i n ( θ ) d θ d ϕ 2 π = ϕ 2 π C D F ( θ ) = ∫ 0 2 π ∫ 0 θ s i n ( θ ) d θ d ϕ ∫ 0 2 π ∫ 0 π / 2 s i n ( θ ) d θ d ϕ = ∫ 0 2 π ∫ 0 θ s i n ( θ ) d θ d ϕ 2 π = 1 − c o s ( θ ) CDF(\phi)=\frac{\int_{0}^{\phi}\int_{0}^{\pi/2}sin(\theta)\rm{d}\theta\rm{d}\phi}{\int_{0}^{2\pi}\int_{0}^{\pi/2}sin(\theta)\rm{d}\theta\rm{d}\phi}=\frac{\int_{0}^{\phi}\int_{0}^{\pi/2}sin(\theta)\rm{d}\theta\rm{d}\phi}{2\pi}=\frac{\phi}{2\pi} \\ CDF(\theta)=\frac{\int_{0}^{2\pi}\int_{0}^{\theta}sin(\theta)\rm{d}\theta\rm{d}\phi}{\int_{0}^{2\pi}\int_{0}^{\pi/2}sin(\theta)\rm{d}\theta\rm{d}\phi}=\frac{\int_{0}^{2\pi}\int_{0}^{\theta}sin(\theta)\rm{d}\theta\rm{d}\phi}{2\pi}=1-cos(\theta) CDF(ϕ)=02π0π/2sin(θ)dθdϕ0ϕ0π/2sin(θ)dθdϕ=2π0ϕ0π/2sin(θ)dθdϕ=2πϕCDF(θ)=02π0π/2sin(θ)dθdϕ02π0θsin(θ)dθdϕ=2π02π0θsin(θ)dθdϕ=1cos(θ)
对应的逆函数分别为:
C D F − 1 ( ϕ ′ ) = 2 π × ϕ ′ C D F − 1 ( θ ′ ) = a r c c o s ( 1 − θ ′ ) CDF^{-1}(\phi') = 2\pi \times \phi' \\ CDF^{-1}(\theta') = arccos(1-\theta') CDF1(ϕ)=2π×ϕCDF1(θ)=arccos(1θ)
之后在[0,1]之间均匀采样随机变量 u 1 , u 2 u1,u2 u1,u2,然后令:
ϕ = C D F − 1 ( u 1 ) = 2 π × u 1 θ = C D F − 1 ( u 2 ) = a r c o s ( 1 − u 2 ) \phi = CDF^{-1}(u1)=2\pi \times u1 \\ \theta = CDF^{-1}(u2)=arcos(1-u2) ϕ=CDF1(u1)=2π×u1θ=CDF1(u2)=arcos(1u2)
根据上式计算得到的 ( ϕ , θ ) (\phi,\theta) (ϕ,θ)就满足在半球面上按照面积均匀分布。

下面是采样python代码和结果(需要注意代码中笛卡尔坐标系的Y轴和Z轴做了交换):

代码:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D


def uniform_sample_hemisphere(n_samples):
    points = []
    for _ in range(n_samples):
        u1 = np.random.rand()
        u2 = np.random.rand()
        
        phi = 2 * np.pi * u1   # 计算方位角
        theta = np.arccos(1.0-u2)  # 计算极角

        # 转换到笛卡尔坐标系
        x = np.sin(theta) * np.cos(phi)
        y = np.sin(theta) * np.sin(phi)
        z = np.cos(theta)

        points.append((x, y, z))
    return np.array(points)


# 生成样本
n_samples = 5000
samples = uniform_sample_hemisphere(n_samples)

# 3D 可视化
fig = plt.figure(figsize=(12, 6))

# 绘制 3D 采样
ax1 = fig.add_subplot(121, projection='3d')
ax1.scatter(samples[:, 0], samples[:, 1], samples[:, 2], alpha=0.6, s=1)
ax1.set_xlabel('X axis')
ax1.set_ylabel('Y axis')
ax1.set_zlabel('Z axis')
ax1.set_title('Uniform Sampling on Hemisphere')

# 绘制 x-y 平面映射
ax2 = fig.add_subplot(122)
ax2.scatter(samples[:, 0], samples[:, 1], alpha=0.6, s=1)
ax2.set_xlabel('X axis')
ax2.set_ylabel('Y axis')
ax2.set_title('Projection onto XY Plane')
ax2.axis('equal')

plt.tight_layout()
plt.show()

可视化结果:
球面均匀采样

2.在半球上使用cos加权采样

对于半球面上的cos加权均匀采样,PDF应与 微元面积 × c o s ( θ ) 微元面积\times cos(\theta) 微元面积×cos(θ)成正比,即在 θ \theta θ越小的区域采样概率越大,在 θ \theta θ越大的区域概率越小,那么对于 ϕ \phi ϕ θ \theta θ的累计密度函数应该为:
C D F ( ϕ ) = ∫ 0 ϕ ∫ 0 π / 2 c o s ( θ ) s i n ( θ ) d θ d ϕ ∫ 0 2 π ∫ 0 π / 2 c o s ( θ ) s i n ( θ ) d θ d ϕ = ∫ 0 ϕ ∫ 0 π / 2 c o s ( θ ) s i n ( θ ) d θ d ϕ π = ϕ / 2 π = ϕ 2 π C D F ( θ ) = ∫ 0 2 π ∫ 0 θ c o s ( θ ) s i n ( θ ) d θ d ϕ ∫ 0 2 π ∫ 0 π / 2 c o s ( θ ) s i n ( θ ) d θ d ϕ = ∫ 0 2 π ∫ 0 θ c o s ( θ ) s i n ( θ ) d θ d ϕ π = π × s i n 2 ( θ ) π = s i n 2 ( θ ) = 1 − c o s 2 ( θ ) CDF(\phi)=\frac{\int_{0}^{\phi}\int_{0}^{\pi/2}cos(\theta)sin(\theta)\rm{d}\theta\rm{d}\phi}{\int_{0}^{2\pi}\int_{0}^{\pi/2}cos(\theta)sin(\theta)\rm{d}\theta\rm{d}\phi}=\frac{\int_{0}^{\phi}\int_{0}^{\pi/2}cos(\theta)sin(\theta)\rm{d}\theta\rm{d}\phi}{\pi}=\frac{\phi/2}{\pi}=\frac{\phi}{2\pi} \\ CDF(\theta)=\frac{\int_{0}^{2\pi}\int_{0}^{\theta}cos(\theta)sin(\theta)\rm{d}\theta\rm{d}\phi}{\int_{0}^{2\pi}\int_{0}^{\pi/2}cos(\theta)sin(\theta)\rm{d}\theta\rm{d}\phi}=\frac{\int_{0}^{2\pi}\int_{0}^{\theta}cos(\theta)sin(\theta)\rm{d}\theta\rm{d}\phi}{\pi}=\frac{\pi \times sin^{2}(\theta)}{\pi} = sin^{2}(\theta)=1-cos^2(\theta) CDF(ϕ)=02π0π/2cos(θ)sin(θ)dθdϕ0ϕ0π/2cos(θ)sin(θ)dθdϕ=π0ϕ0π/2cos(θ)sin(θ)dθdϕ=πϕ/2=2πϕCDF(θ)=02π0π/2cos(θ)sin(θ)dθdϕ02π0θcos(θ)sin(θ)dθdϕ=π02π0θcos(θ)sin(θ)dθdϕ=ππ×sin2(θ)=sin2(θ)=1cos2(θ)
对应的逆函数分别为:
C D F − 1 ( ϕ ′ ) = 2 π × ϕ ′ C D F − 1 ( θ ′ ) = a r c c o s ( 1 − θ ′ ) CDF^{-1}(\phi') = 2\pi \times \phi' \\ CDF^{-1}(\theta') = arccos(\sqrt{1-\theta'}) CDF1(ϕ)=2π×ϕCDF1(θ)=arccos(1θ )
之后在[0,1]之间均匀采样随机变量 u 1 , u 2 u1,u2 u1,u2,然后令:
ϕ = C D F − 1 ( u 1 ) = 2 π × u 1 θ = C D F − 1 ( u 2 ) = a r c o s ( 1 − u 2 ) \phi = CDF^{-1}(u1)=2\pi \times u1 \\ \theta = CDF^{-1}(u2)=arcos(\sqrt{1-u2}) ϕ=CDF1(u1)=2π×u1θ=CDF1(u2)=arcos(1u2 )
根据上式计算得到的 ( ϕ , θ ) (\phi,\theta) (ϕ,θ)就满足在半球面上按照 微元面积 × c o s ( θ ) 微元面积\times cos(\theta) 微元面积×cos(θ)加权分布。

下面是采样python代码和结果(需要注意代码中笛卡尔坐标系的Y轴和Z轴做了交换):

代码
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D


def uniform_sample_hemisphere(n_samples):
    points = []
    for _ in range(n_samples):
        u1 = np.random.rand()
        u2 = np.random.rand()
        phi = 2 * np.pi * u1   # 计算方位角
        theta = np.arccos(np.sqrt(1 - u2))  # 计算极角

        # 转换到笛卡尔坐标系
        x = np.sin(theta) * np.cos(phi)
        y = np.sin(theta) * np.sin(phi)
        z = np.cos(theta)

        points.append((x, y, z))
    return np.array(points)


# 生成样本
n_samples = 5000
samples = uniform_sample_hemisphere(n_samples)

# 3D 可视化
fig = plt.figure(figsize=(12, 6))

# 绘制 3D 采样
ax1 = fig.add_subplot(121, projection='3d')
ax1.scatter(samples[:, 0], samples[:, 1], samples[:, 2], alpha=0.6, s=1)
ax1.set_xlabel('X axis')
ax1.set_ylabel('Y axis')
ax1.set_zlabel('Z axis')
ax1.set_title('Uniform Sampling on Hemisphere')

# 绘制 x-y 平面映射
ax2 = fig.add_subplot(122)
ax2.scatter(samples[:, 0], samples[:, 1], alpha=0.6, s=1)
ax2.set_xlabel('X axis')
ax2.set_ylabel('Y axis')
ax2.set_title('Projection onto XY Plane')
ax2.axis('equal')

plt.tight_layout()
plt.show()

结果

球面cos加权采样

三、参考

[1].Sampling the hemisphere

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/887547.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何使用 Python 读取数据量庞大的 excel 文件

使用 pandas.read_excel 读取大文件时,的确会遇到性能瓶颈,特别是对于10万行20列这种规模的 .xlsx 文件,常规的 pandas 方法可能会比较慢。 要提高读取速度,关键是找到更高效的方式处理 Excel 文件,特别是在 Python 的…

51单片机学习第六课---B站UP主江协科技

DS18B20 1、基本知识讲解 2、DS18B20读取温度值 main.c #include<regx52.h> #include"delay.h" #include"LCD1602.h" #include"key.h" #include"DS18B20.h"float T; void main () {LCD_Init();LCD_ShowString(1,1,"temp…

Qt之TCP收发图片的例子

一.效果 二.实现 1.发图片 void MainWindow::slotSendImage() {matrix.rotate(90);QPixmap tempPixmap = pixmap.transformed(matrix);QBuffer buffer;tempPixmap.save(&buffer,"jpg");ui->labelImage->setPixmap(tempPixmap);int dataLength = buffer.d…

软考鸭微信小程序:助力软考备考的便捷工具

一、软考鸭微信小程序的功能 “软考鸭”微信小程序是一款针对软考考生的备考辅助工具&#xff0c;提供了丰富的备考资源和功能&#xff0c;帮助考生提高备考效率&#xff0c;顺利通过考试。其主要功能包括&#xff1a; 历年试题库&#xff1a;小程序内集成了历年软考试题&…

HarmonyOs 查看官方文档使用弹窗

1. 学会查看官方文档 HarmonyOS跟上网上的视频学习一段时间后&#xff0c;基本也就入门了&#xff0c;但是有一些操作网上没有找到合适教学的视频&#xff0c;这时&#xff0c;大家就需要养成参考官方文档的习惯了&#xff0c;因为官方的开发文档是我们学习深度任何一门语言或…

004集—— txt格式坐标写入cad(CAD—C#二次开发入门)

如图所示原始坐标格式&#xff0c;xy按空格分开&#xff0c;将坐标按顺序在cad中画成多段线&#xff1a; 坐标xy分开并按行重新输入txt&#xff0c;效果如下&#xff1a; 代码如下 &#xff1a; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Runtime; us…

AI模型部署初认识

AI部署这个词儿大家肯定不陌生&#xff0c;可能有些小伙伴还不是很清楚这个是干嘛的&#xff0c;但总归是耳熟能详了。 近些年来&#xff0c;在深度学习算法已经足够卷卷卷之后&#xff0c;深度学习的另一个偏向于工程的方向–部署工业落地&#xff0c;才开始被谈论的多了起来…

Pikachu-File Inclusion-远程文件包含

远程文件包含漏洞 是指能够包含远程服务器上的文件并执行。由于远程服务器的文件是我们可控的&#xff0c;因此漏洞一旦存在&#xff0c;危害性会很大。但远程文件包含漏洞的利用条件较为苛刻&#xff1b;因此&#xff0c;在web应用系统的功能设计上尽量不要让前端用户直接传变…

水下声呐数据集,带标注

水下声呐数据集&#xff0c;带标注 水下声呐数据集 数据集名称 水下声呐数据集 (Underwater Sonar Dataset) 数据集概述 本数据集是一个专门用于训练和评估水下目标检测与分类模型的数据集。数据集包含大量的水下声呐图像&#xff0c;每张图像都经过专业标注&#xff0c;标明…

银河麒麟桌面操作系统修改默认Shell为Bash

银河麒麟桌面操作系统修改默认Shell为Bash &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 在银河麒麟桌面操作系统&#xff08;ARM版&#xff09;中&#xff0c;若要将默认Shell从Dash改为Bash&#xff0c;可执行以下步骤&#xff1a; 打开…

记一次炉石传说记牌器 Crash 排查经历

大家好这里是 Geek技术前线。最近在打炉石过程中遇到了HSTracker记牌器的一个闪退问题&#xff0c;尝试性排查了下原因。这里简单记录一下 最近炉石国服回归&#xff1b;由于设备限制&#xff0c;我基本只会在 Mac 上打炉石。并且由于主要打竞技场&#xff0c;所以记牌器是必不…

河南移动:核心营业系统稳定运行超300天,数据库分布式升级实践|OceanBase案例

河南移动&#xff0c;作为电信全业务运营企业&#xff0c;不仅拥有庞大的客户群体和业务规模&#xff0c;还引领着业务产品与服务体系的创新发展。河南移动的原有核心营业系统承载着超过6000万的庞大用户量&#xff0c;管理着超过80TB的海量数据&#xff0c;因此也面临着数据规…

AI类课程的笔记

信息论、导论、模式识别&#xff08;数据挖掘&#xff09;、语义网络与知识图谱、深度学习、强化学习 &#xff08;零&#xff09;信息论 详见另一篇博文 信息论自总结笔记(仍然在更新)_信息论也更新了-CSDN博客https://blog.csdn.net/sinat_27382047/article/details/12690…

Elasticsearch 实战应用

Elasticsearch 实战应用 引言 Elasticsearch 是一个分布式、RESTful 风格的搜索和分析引擎&#xff0c;能够快速、实时地处理大规模数据&#xff0c;广泛应用于全文搜索、日志分析、推荐系统等领域。在这篇博客中&#xff0c;我们将从 Elasticsearch 的基本概念入手&#xff…

无神论文解读之ControlNet:Adding Conditional Control to Text-to-Image Diffusion Models

一、什么是ControlNet ControlNet是一种能够控制模型生成内容的方法&#xff0c;能够对文生图等模型添加限制信息&#xff08;边缘、深度图、法向量图、姿势点图等&#xff09;&#xff0c;在当今生成比较火的时代很流行。 这种方法使得能够直接提供空间信息控制图片以更细粒…

Hive数仓操作(十七)

一、Hive的存储 一、Hive 四种存储格式 在 Hive 中&#xff0c;支持四种主要的数据存储格式&#xff0c;每种格式有其特点和适用场景&#xff0c;不过一般只会使用Text 和 ORC &#xff1a; 1. Text 说明&#xff1a;Hive 的默认存储格式。存储方式&#xff1a;行存储。优点…

设计模式、系统设计 record part03

创建者模式 1.创建、使用&#xff0c;二者分离 2.降低&#xff0c;耦合度 3.使用者&#xff0c;不用关注&#xff0c;对象的创建细节 工厂模式&#xff1a; 1.对象由工厂生产&#xff0c; 2.使用者与工厂交流&#xff0c;不与对象直接打交道&#xff0c; 3.在工厂里直接更换对象…

快手:数据库升级实践,实现PB级数据的高效管理|OceanBase案例

本文作者&#xff1a;胡玉龙&#xff0c;快手技术专家 快手在较初期采用了OceanBase 3.1版本成功替换了多个核心业务、数百套的MySQL集群。至2023年&#xff0c;快手的数据量已突破800TB大关&#xff0c;其中最大集群的数据量更是达到了数百TB级别。为此&#xff0c;快手将数据…

静止坐标系和旋转坐标系变换的线性化,锁相环线性化通用推导

将笛卡尔坐标系的电压 [ U x , U y ] [U_x, U_y] [Ux​,Uy​] 通过旋转变换(由锁相环角度 θ P L L \theta_{PLL} θPLL​ 控制)转换为 dq 坐标系下的电压 [ U d , U q ] [U_d, U_q] [Ud​,Uq​]。这个公式是非线性的,因为它涉及到正弦和余弦函数。 图片中的推导过程主要…

[C++]使用C++部署yolov11目标检测的tensorrt模型支持图片视频推理windows测试通过

官方框架&#xff1a; https://github.com/ultralytics/ultralytics yolov8官方最近推出yolov11框架&#xff0c;标志着目标检测又多了一个检测利器&#xff0c;于是尝试在windows下部署yolov11的tensorrt模型&#xff0c;并最终成功。 重要说明&#xff1a;安装环境视为最基…