6D空间中的蒙特卡罗采样

时间:2015-08-12 12:04:59

标签: java sampling montecarlo

我正在为两个对象(A和B)的刚体叠加编写java代码。对象A固定在空间中,而对象B可以在空间中自由移动。目标是在A和B之间获得最佳匹配。

为了找到A和B之间的最佳拟合,我想对B的可能姿势进行采样。为此我试图实现基于蒙特卡罗的采样程序。但我不确定我是否正确地做到了。我阅读了谷歌上发现的几篇文章,但我对随机变量的概率分布和移动验收标准感到有些困惑。

由于物体B可以在空间中平移和旋转,我定义了6个变量(6D空间),这些变量与x,y,z平移和旋转相对应。我做50000随机动作。每次移动后,我都会检查A和B的新姿势之间是否合适。下面是我现在正在使用的简化java代码。

object A;
object B;
object B_NewPose;
double winnerScore;

for (int iter = 0; iter < 50000; iter++) {

    double x_tranlation = 0; //translate in X (max translation is +-10 Amstrong)
    double y_tranlation = 0; //translate in Y (max translation is +-10 Amstrong)
    double z_tranlation = 0; //translate in Z (max translation is +-10 Amstrong)

    double x_rotation = 0; //rotate around X (max rotation is 360 degree)
    double y_rotation = 0; //rotate around Y (max rotation is 360 degree)
    double z_rotation = 0; //rotate around Z (max rotation is 360 degree)

    //random selection of the axes for translation and rotation
    int axis_Idx = getRanNumberInt(0, 2); // (0=x, 1=y and 2=z)

    //get the amount of translation (can be right (+) or left(-))
    double translate = getRanNumberDouble(0, 10);
    if (axis_Idx==0) {
       x_tranlation=translate;  
    }

    if (axis_Idx==1) {
       y_tranlation=translate;  
    }

    if (axis_Idx==2) {
       z_tranlation=translate;  
    }

    //get the amount of rotation
    double rotation = getRanNumberDouble(0, 360);
    if (axis_Idx==0) {
       x_rotation=rotation; 
    }

    if (axis_Idx==1) {
       y_rotation=rotation; 
    }

    if (axis_Idx==2){
       z_rotation=rotation; 
    }

    //Now move the object: translation and rotation
    B_NewPose= moveTheObj(object B, x_tranlation, y_tranlation, z_tranlation, x_rotation, y_rotation, z_rotation);

    //Check how good is the fit between A and N_NewPose
    double score = calculateFit(A, B_NewPose);

    if (score> oldScore){
        oldScore=score;
        B=B_NewPose;                
    }

    }

如果有人能指导我正确的方向或帮助我澄清这个场景中的蒙特卡罗算法,我将非常感激。 非常感谢提前。

1 个答案:

答案 0 :(得分:1)

翻译看起来不错,它们是线性的

旋转,我不确定它在球体上是否均匀。所以,您可能会考虑这样一种情况:您可能只想随意定位对象,因为您并不关心旧方向是否重要

为此,有一个非常简单的算法来生成新的物体轴/方向位置

phi   = 2.0 * PI * getRanNumberDouble(0.0, 1.0);
csth  = 2.0 * getRanNumberDouble(0.0, 1.0) - 1.0;
snth  = sqrt((1.0 - csth)*(1.0 + csth));
wx = snth * sin(phi);
wy = snth * cos(phi);
wz = csth;

这将为您提供标准化的向量(wx, wy, wz),它将是您的对象新方向/轴。 如果你真的需要随机旋转,你可能想要采样均匀的球体矢量来旋转,就像上面的方法一样,并添加旋转角度

angle = 2.0 * PI * getRanNumberDouble(0.0, 1.0);

然后(wx, wy, wz, angle)基本上是一个均匀分布的四元数,你可以用它来构建旋转操作(使用四元数,或者用它制作矩阵或Rodriges公式,无论你喜欢什么)。

我正在使用弧度