如何使箭头远离一个点?

How to orient arrow away from a point?

我给出了一个以xyz为起点,以abc为方向的箭头(不是箭尖,而是以坐标系原点为原点的方向向量)和一个点p。我想让箭头始终远离点,但我不确定我的解决方案是否正确。我天真的做法是这样的:

void pointArrowAwayFromPoint(Eigen::VectorXd &arrow, pcl::PointXYZRGB point){
  bool invert = false;
  for(int i = 0; i < 3; i++){
    if(arrow[i] < point.data[i] && arrow[i+3] > 0){
      invert = true;
      break;
    }
    else if(arrow[i] > point.data[i] && arrow[i+3] < 0){
      invert = true;
      break;
    }
  }
  if(invert){
    for(int i = 3; i < 6; i++){
      arrow[i] *= -1;
    }
  }
}

vectorXd 在前 3 个数组元素中包含 xyz,在接下来的 3 个元素中包含 abc。

给定 arrow 的位置和 point 的位置,只需减去

即可得到指向远离 point 的方向:
arrow.tail<3>() = arrow.head<3> - point.getVector3fMap();

您可能希望将方向归一化,在这种情况下,您可以使用 Eigen 的 Block operations for vectors 来获得 abc:

arrow.tail<3>().normalize();

乍一看,您的解决方案并不适用于所有情况。您可以简单地使用适当的向量算法:

  • 将您的 abc(定义为从 [0, 0, 0] 开始的向量的方向)分配给 3d 向量
  • 通过从 POINT
  • 中减去箭头原点来计算 3d 向量
  • 计算这两个向量之间的角度

示例:

Eigen::VectorXd arrow(6);
// simple arrow pointing in the direction of X
arrow[3] = 1.0;
Eigen::Vector3d point{-2, 1, 1};
Eigen::Vector3d v1 = arrow.tail<3>();
Eigen::Vector3d v2 = point - arrow.head<3>();
double cosX = v1.dot(v2)/(v1.norm()*v2.norm());
std::cout << "angle between arrow and the point: " << std::acos(cosX) << std::endl;

如果大于Pi/2,则箭头向外看。