我有一个三维的2D平面:x + y + z = 1,我想在平面上生成随机点(x,y,z)。如何选择这些点以使它们均匀分布?
如评论中所述,问题尚未明确。尽管这是一个有趣的问题。因为没有给出分配我只选了一个。以下是我将回答的更精确的(?)/一般(?)问题:
假设我在
P
定义的R^3
中有一架ax + by + cz = d
飞机。让
c
在距离原点最近的P
上。如何在
P
的某个半径r
内统一选择c
上的一个点?
让qazxsw poi。 qazxsw poi是qazxsw poi的正常向量。
n = (a,b,c)
上生成任何非零向量,称之为n
。您可以通过将P
的任意积分与任何与ax + by + cz = d
不平行的非零向量相乘来实现此目的。w
来做到这一点。n
n
为0,我们就完成了。除此以外:w
。n
scale = random.range(min,max)
这是我的算法的C实现。我从头开始编写了所有的矢量机器,所以它有点乱。我没有彻底测试过这个。
[0,2pi)
Eugene几乎是正确的:在区间[0,1]上生成两个随机数,称之为A,B。然后x = min(A,B),y = max(A,B) - x,z = 1 - (x + y)。基本上,您在线[0,1]上选择两个点,并且您的三个坐标是由这两个点定义的三个区间。
我先给你一个简单的算法
http://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula
现在让我们看看该算法的实现
此代码将生成任何类型的数字(+ ve或-ve)
direction = direction / direction.magnitude
只需使用d
为随机数生成器播种,并使用http://en.wikipedia.org/wiki/Distance_from_a_point_to_a_plane分配随机数。
如果您需要创建具有范围的随机数,请使用 origin of the ray = vector3.zero + c * ( n )
,其中maxnumber是您想要的最大值。
如果您希望所有数字都是正数,那么试试这个
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
typedef struct {
double x, y, z;
} vec3;
vec3 vec(double x, double y, double z);
vec3 crossp(vec3 u, vec3 v);
vec3 add(vec3 u, vec3 v);
double dotp(vec3 u, vec3 v);
double norm2(vec3 u);
double norm(vec3 u);
vec3 scale(vec3 u, double s);
vec3 normalize(vec3 u);
void print_vec3(vec3 u);
// generates a random point on the plane ax + by + cz = d
vec3 random_on_plane(double r, double a, double b, double c, double d) {
// The normal vector for the plane
vec3 n = vec(a, b, c);
// create a normal vector on the plane ax + by + cz = 0
// we take any vector not parallel to n
// and find the cross product
vec3 w;
if (n.x == 0)
w = crossp(n, vec(1,0,0));
else
w = crossp(n, vec(0,0,1));
// rotate the vector around n by a random angle
// using Rodrigues' rotation formula
// http://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula
double theta = ((double)rand() / RAND_MAX) * M_PI;
vec3 k = normalize(n);
w = add(scale(w, cos(theta)),
scale(crossp(k, w), sin(theta)));
// Scale the vector fill our disk.
// If the radius is zero, generate unit vectors
if (r == 0) {
w = scale(w, r/norm(w));
} else {
double rand_r = ((double)rand() / RAND_MAX) * r;
w = scale(w, rand_r/norm(w));
}
// now translate the vector from ax + by + cz = 0
// to the plane ax + by + cz = d
// http://en.wikipedia.org/wiki/Distance_from_a_point_to_a_plane
if (d != 0) {
vec3 t = scale(n, d / norm2(n));
w = add(w, t);
}
return w;
}
int main(void) {
int i;
srand(time(NULL));
for (i = 0; i < 100; i++) {
vec3 r = random_on_plane(10, 1, 1, 1, 1);
printf("random v = ");
print_vec3(r);
printf("sum = %f, norm = %f\n", r.x + r.y + r.z, norm(r));
}
}
vec3 vec(double x, double y, double z) {
vec3 u;
u.x = x;
u.y = y;
u.z = z;
return u;
}
vec3 crossp(vec3 u, vec3 v) {
vec3 w;
w.x = (u.y * v.z) - (u.z * v.y);
w.y = (u.z * v.x) - (u.x * v.z);
w.z = (u.x * v.y) - (u.y * v.x);
return w;
}
double dotp(vec3 u, vec3 v) {
return (u.x * v.x) + (u.y * v.y) + (u.z * v.z);
}
double norm2(vec3 u) {
return dotp(u, u);
}
double norm(vec3 u) {
return sqrt(norm2(u));
}
vec3 scale(vec3 u, double s) {
u.x *= s;
u.y *= s;
u.z *= s;
return u;
}
vec3 add(vec3 u, vec3 v) {
u.x += v.x;
u.y += v.y;
u.z += v.z;
return u;
}
vec3 normalize(vec3 u) {
return scale(u, 1/norm(u));
}
void print_vec3(vec3 u) {
printf("%f %f %f\n", u.x, u.y, u.z);
}
警告 上面的代码可能需要一些时间来执行,所以不要指望即时结果