Julia如何实现随机抛撒单位长度细棒并统计触碰红线的数量
解决方案
随机抛撒实现方法
细棒的随机状态由两个独立的随机变量决定,不需要固定起点在原点:
- 位置参数:取细棒的中点作为位置锚点。假设平行红线的间距为
d(通常取d≥1即可),由于红线是周期性排列的,仅需要将中点的x坐标在[0, d)区间取均匀随机值即可,y坐标不影响碰撞判定,可任意生成或者直接忽略。 - 朝向参数:你现有的生成二维随机正态向量再归一化的逻辑完全可用,也可以简化为直接生成
[0, π)区间的均匀随机角度θ,两种方式都能得到无偏的随机朝向。
触碰红线判定逻辑
判定规则非常简单:只要细棒中点到最近红线的距离,小于等于细棒半长在垂直于红线方向的投影长度,就说明细棒碰到了红线。
以红线为平行于y轴、间距为d的竖线为例:
- 计算中点到最近红线的距离:
min(中点x坐标, d - 中点x坐标) - 计算细棒半长在x轴(垂直红线方向)的投影:
0.5 * |cos(细棒朝向角度θ)|,如果你用归一化方向向量计算,直接取向量x分量的绝对值即可,不需要额外算角度。 - 只要前者小于等于后者,就计入触碰计数。
代码示例
沿用你原有朝向生成逻辑的示例(类Julia语法)
using LinearAlgebra function count_hit(num_trials::Int, line_spacing::Float64=2.0) hit = 0 d = line_spacing for _ in 1:num_trials # 随机中点x坐标 x_mid = rand() * d # 你原有的随机朝向逻辑 a = [randn(), randn()] dir_vec = a / norm(a) cos_theta = abs(dir_vec[1]) # 碰撞判定 if min(x_mid, d - x_mid) ≤ 0.5 * cos_theta hit += 1 end end return hit end # 测试:抛10000次,红线间距2 println(count_hit(10000, 2.0))
Python版本示例
import random import math def count_hit(num_trials, line_spacing=2.0): hit = 0 d = line_spacing for _ in range(num_trials): x_mid = random.uniform(0, d) theta = random.uniform(0, math.pi) if min(x_mid, d - x_mid) <= 0.5 * abs(math.cos(theta)): hit += 1 return hit print(count_hit(10000, 2.0))
如果红线是水平方向的,只需要把判定逻辑中的x坐标换成y坐标,cosθ换成sinθ即可,逻辑完全一致。
内容的提问来源于stack exchange,提问作者Struggling_Student
相关产品推荐
相关产品推荐

