仓库质心VBA

时间:2017-07-26 17:26:05

标签: excel vba excel-vba excel-2010 centroid

我正在尝试编写一个公式,该公式考虑了'x'地址的'n'个客户以及他们订购了多少('q')。我希望公式然后打印出'质心'仓库应该是最佳位置的纬度/经度。

我更喜欢它是override func viewDidLoad() { super.viewDidLoad() addNavBarImage() let URL = Bundle.main.url(forResource: "homedocapp", withExtension: "mp4") Player = AVPlayer.init(url: URL!) PlayerLayer = AVPlayerLayer(player: Player) PlayerLayer.videoGravity = AVLayerVideoGravityResizeAspect PlayerLayer.frame = view.layer.bounds Player.actionAtItemEnd = AVPlayerActionAtItemEnd.none Player.play() view.layer.insertSublayer(PlayerLayer, at: 0) NotificationCenter.default.addObserver(self, selector: #selector(playerItemReachEnd(notification:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: Player.currentItem) 等命令。

感谢您的帮助。

修改

由于有些人可能会认为这篇文章太宽泛或者没有足够的信息 - 我会提供一个旧的代码。

此代码采用我输入的纬度和经度,然后考虑装运数量,然后继续告诉我新仓库应该在哪里。它太旧了,我不确定它是如何工作的。

=getCentroid

1 个答案:

答案 0 :(得分:1)

这里有一些代码可以处理计算球体表面加权质心的数学部分:

'the following code assumes that A is a 4 column, 1-based, 2-dimensional array whose
'first three columns are the x,y,z coordinats of a point on a sphere centered at the origin
'and whose 4th column is the mass at that point
'returns a 0-based variant array of the x,y,z coordinates of the centroid

Function SphericalCentroid(A As Variant) As Variant
    Dim r As Double 'radius of sphere
    Dim pm As Double 'point-mass
    Dim m As Double 'total mass
    Dim mxy As Double, mxz As Double, myz As Double 'moments about coordinate planes
    Dim xbar As Double, ybar As Double, zbar As Double 'true centroid
    Dim d As Double 'distance of true centroid from center -- used to project to surface
    Dim i As Long, n As Long

    If TypeName(A) = "Range" Then A = A.Value
    n = UBound(A)
    r = Sqr(A(1, 1) ^ 2 + A(1, 2) ^ 2 + A(1, 3) ^ 2)
    For i = 1 To n
        pm = A(i, 4)
        m = m + pm
        myz = myz + pm * A(i, 1)
        mxz = mxz + pm * A(i, 2)
        mxy = mxy + pm * A(i, 3)
    Next i
    xbar = myz / m
    ybar = mxz / m
    zbar = mxy / m
    d = Sqr(xbar ^ 2 + ybar ^ 2 + zbar ^ 2)
    If d < 0.001 * r Then 'located at the center -- return pole
        SphericalCentroid = Array(0, 0, r)
    Else
        SphericalCentroid = Array(xbar * r / d, ybar * r / d, zbar * r / d)
    End If
End Function

以下屏幕截图显示了如何使用它:

enter image description here

在上面我使用了单元格=SphericalCentroid(A2:D4)中的数组公式(A5:C5)(使用Ctrl + Shift + Enter输入)。

代码首先计算三维空间中的质心(将其定位在球体内部的某个位置),然后将其投影到球体本身上。

要将此问题用于您的问题,您需要创建一个包装函数,该函数从纬度/经度转换为笛卡尔坐标(将地球近似为球体 - 确实存在问题),调用上述函数,然后转换回纬度/经度。

On Edit 为了好玩,我写了一个包装函数:

'the following function takes a 3-column range, the first column is decimal latitude,
'the second is decimal longitude (assuming in North America),
'the third is number of shipments from that location
'the return value is the decimal latitude and longitude of
'the centroid

Function GetCentroid(data As Range) As Variant
    Dim r As Double
    Dim lat As Double, lon As Double
    Dim x As Double, y As Double, z As Double
    Dim A As Variant
    Dim i As Long, n As Long
    Dim centroid As Variant

    r = 3959 'radius of earth
    n = data.Rows.Count
    ReDim A(1 To n, 1 To 4)

    With Application.WorksheetFunction
        For i = 1 To n
            lat = .Radians(data.Cells(i, 1).Value)
            lon = .Radians(data.Cells(i, 2).Value)
            A(i, 1) = r * Cos(lat) * Cos(lon)
            A(i, 2) = r * Cos(lat) * Sin(lon)
            A(i, 3) = r * Sin(lat)
            A(i, 4) = data.Cells(i, 3).Value
        Next i
        centroid = SphericalCentroid(A)
        x = centroid(0)
        y = centroid(1)
        z = centroid(2)
        lat = .Degrees(.Asin(z / r))
        lon = .Degrees(.Atan2(x, y))
    End With
    GetCentroid = Array(lat, lon)
End Function

用过:

enter image description here

输入列表中的三个位置分别位于克利夫兰,辛辛那提和匹兹堡,返回的质心位于俄亥俄州中部(有点接近Zanesville - 看起来似乎有道理)。

我怀疑它比粗略的启发式更好,但是它给出了一个好位置的概念。