使用两个坐标图层计算三维空间中两点之间的距离

时间:2015-04-19 12:05:37

标签: c# 3d

我需要计算3D空间中两点之间的距离。我正在使用的坐标系是Int64来获取扇区,并且在每个扇区内Int32用于获取本地位置。所以本质上它是一个Int96位坐标系。

如果没有大量的if语句检查边界,我们不确定这是如何工作的,因此可能有更聪明的方法。

有人可以帮忙吗?

PS! Double的精度损失是可以接受的。我不能使用不安全的代码。 BigInteger不是一个选项,因为代码必须在Unity中运行。

样本可以是:

public struct SectorPos
{
    public readonly Int64 X;
    public readonly Int64 Y;
    public readonly Int64 Z;

    public SectorPos(Int64 x, Int64 y, Int64 z)
    {
        X = x;
        Y = y;
        Z = z;
    }
}
public struct LocalPos
{
    public readonly Int32 X;
    public readonly Int32 Y;
    public readonly Int32 Z;

    public LocalPos(Int32 x, Int32 y, Int32 z)
    {
        X = x;
        Y = y;
        Z = z;
    }
}

struct Pos
{
    public readonly SectorPos Sector;
    public readonly LocalPos Local;

    public Pos(SectorPos sector, LocalPos local)
    {
        Sector = sector;
        Local = local;
    }
}

void Test()
{
    // Should be 1:
    Double d1 = Distance(new Pos(new SectorPos(0, 0, 0), 
                                 new LocalPos(Int32.MaxValue, 0, 0)), 
                         new Pos(new SectorPos(0, 1, 0), 
                                 new LocalPos(Int32.MinValue, 0, 0)));
    // Should be -1: (EDIT: Should be 1 of course)
    Double d2 = Distance(new Pos(new SectorPos(0, -2, 0), 
                                 new LocalPos(Int32.MaxValue, 0, 0)), 
                         new Pos(new SectorPos(0, -3, 0), 
                                 new LocalPos(Int32.MinValue, 0, 0)));
    // Should be Int32.MaxValue+1:
    Double d3 = Distance(new Pos(new SectorPos(1, 0, 0), 
                                 new LocalPos(Int32.MaxValue, 0, 0)), 
                         new Pos(new SectorPos(3, 0, 0), 
                                 new LocalPos(Int32.MinValue, 0, 0))); 
}

1 个答案:

答案 0 :(得分:1)

我假设Sector X=1, Local X=int.MinValueSector X=0, Local X=int.MaxValue大致相同。

这意味着1的每个扇区步骤的实际大小为int.MaxValue*2

要获得绝对X位置,您可以secX * int.MaxValue * 2 + locX

通过在double上执行这些操作避免溢出(而不是在最后尝试强制转换为double)。

所以要把它放在一起,你可以尝试:

public struct AbsolutePos
{
    private const double SEC_FACTOR = int.MaxValue * 2d;
    public readonly double X;
    public readonly double Y;
    public readonly double Z;

    public AbsolutePos(SectorPos secPos, LocalPos locPos)
    {
        X = secPos.X * SEC_FACTOR + locPos.X;
        Y = secPos.Y * SEC_FACTOR + locPos.Y;
        Z = secPos.Z * SEC_FACTOR + locPos.Z;
    }

    public double Distance(AbsolutePos pos)
    {
        // implement 3d distance calculation normally here
    }
}

struct Pos
{
    ...

    public AbsolutePos GetAbsPos()
    {
        return new AbsolutePos(this.Sector, this.Local);
    }
}

然后您可以将其用作:

var pos1 = new Pos(new SectorPos(0, 0, 0), 
                   new LocalPos(Int32.MaxValue, 0, 0));
var pos2 = new Pos(new SectorPos(0, 1, 0), 
                   new LocalPos(Int32.MinValue, 0, 0));
var distance = pos1.GetAbsolutePos().Distance(pos2.GetAbsolutePos());

您可能希望将最终距离除以SEC_FACTOR,具体取决于您希望如何看待它。