繁体   English   中英

使用两个坐标层计算3D空间中两点之间的距离

[英]Calculate distance between two points in 3D space with two coordinate layers

我需要计算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))); 
}

我假设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 ,具体取决于您希望如何看待它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM