我有三维2D平面: x + y + z = 1,我想生成随机点(x ,y,z)在飞机上。如何选择这些点以便均匀分布?
答案 0 :(得分:5)
正如评论中所提到的那样,问题尚未明确。尽管这是一个有趣的问题。因为没有给出分配我只选了一个。以下是我将回答的更精确的(?)/一般(?)问题:
假设
P
由R^3
定义了ax + by + cz = d
中的c
。{/ p>让
P
位于距离原点最近的P
点。如何在
r
的某个半径c
范围内统一选择n = (a,b,c)
上的某个点?
让n
。 P
是与ax + by + cz = d
正常的向量。
在平面w
上生成任何非零向量,将其称为n
。您可以将n
的叉积与任何与w
不平行的非零向量相乘。
在n
中以[0,2pi)
的随机角度围绕direction = direction / direction.magnitude
{}移动d
。您可以使用http://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula。
所以,现在你通过规范化了方向
origin of the ray = vector3.zero + c * ( n )
如果#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);
}
为0,我们就完成了。否则:
计算c =距离Vector3(0,0,0)的平面距离 根据{{3}}。
翻译光线的来源
{{1}}
scale = random.range(min,max)
这是我的算法的C实现。我从头开始编写了所有的矢量机器,所以它有点乱。我没有彻底测试过这个。
{{1}}
答案 1 :(得分:2)
答案 2 :(得分:1)
我先给你一个简单的算法
x = rand()
y = rand()
z = 1 - x - y
现在让我们看一下该算法的实现
此代码将生成任何类型的数字(+ ve或-ve)
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
srand(time(NULL));
int x= ( rand() - rand() ) ;
int y= ( rand() - rand() ) ;
int z=1-x-y;
printf("x=%d y=%d z=%d",x,y,z);
}
只需使用srand()
为随机数生成器播种,然后使用rand()
分配随机数。
如果您需要创建带范围的随机数,请使用rand() % ( maxnumber + 1 )
,其中maxnumber是您想要的最大值。
如果您希望所有数字都是正数,请尝试使用
int main()
{
srand(time(NULL));
int x, y , z = -1;
while ( z < 0 )
{
x = rand() ;
y = rand() ;
z = 1 - (x + y );
}
printf("x=%d y=%d z=%d",x,y,z);
}
警告强>
上面的代码可能需要一些时间才能执行,所以不要期待即时结果