在C中的特定平面中生成随机点

时间:2015-03-30 16:05:41

标签: c algorithm

我有三维2D平面: x + y + z = 1,我想生成随机点(x ,y,z)在飞机上。如何选择这些点以便均匀分布?

3 个答案:

答案 0 :(得分:5)

问题

正如评论中所提到的那样,问题尚未明确。尽管这是一个有趣的问题。因为没有给出分配我只选了一个。以下是我将回答的更精确的(?)/一般(?)问题:

  

假设PR^3定义了ax + by + cz = d中的c。{/ p>      

P位于距离原点最近的P点。

     

如何在r的某个半径c范围内统一选择n = (a,b,c)上的某个点?

算法

nP是与ax + by + cz = d正常的向量。

方向

  1. 在平面w上生成任何非零向量,将其称为n。您可以将n的叉积与任何与w不平行的非零向量相乘。

  2. n中以[0,2pi)的随机角度围绕direction = direction / direction.magnitude {}移动d。您可以使用http://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula

  3. 执行此操作
  4. 所以,现在你通过规范化了方向

  5.  origin of the ray = vector3.zero +  c * ( n )
    

    光线的原点

    1. 如果#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,我们就完成了。否则:

    2. 计算c =距离Vector3(0,0,0)的平面距离 根据{{​​3}}。

    3. 翻译光线的来源

    4. {{1}}

      scale = random.range(min,max)

      所以重点是

      • origin_of_the_ray + scale *(方向_)

      守则

      这是我的算法的C实现。我从头开始编写了所有的矢量机器,所以它有点乱。我没有彻底测试过这个。

      {{1}}

答案 1 :(得分:2)

Eugene几乎是正确的:在区间[0,1]上生成两个随机数,称之为A,B。然后x = min(A,B),y = max(A,B) - x,z = 1 - (x + y)。基本上,你在[0,1]行上选择两个点,你的三个坐标是由这两个点定义的三个区间。

答案 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); 
  }

警告
上面的代码可能需要一些时间才能执行,所以不要期待即时结果