我在Unity中撰寫一個游戲,你的士兵的數量會通過一些觸發器增加/減少。我想把我的士兵物件定位成一個完整的圓,所以即使他們的數量在增加或減少,他們將總是相互靠近(如相同的距離)。我怎樣才能做到這一點?
uj5u.com熱心網友回復:假設你在水平面上作業,你可以為你的每個士兵定義你的旋轉,并在平面上找到那個點,將笛卡爾坐標(x,y)轉換成極坐標(R,fi),將theta加到fi,然后再轉換回笛卡爾坐標。
//繞A旋轉B,角度為theta
private (float x, float y) Rotate(
(float x, float y) A。
(float x, float y) B,
float theta) {
float fi = Math.Atan2(B.y - A.y, B.x - A.x) theta;
float R = Math.Sqrt((A.y - B.y) * (A.y - B.y) (A.x - B.x) * (A.x - B.x)) 。
回傳(A.x R * Math.Cos(fi), A.y R * Math.Sin(fi))。
}
另一個選項做了完全相同的事情,但沒有使用極坐標:
//將B繞A順時針旋轉θ角
private (float x, float y) Rotate(
(float x, float y) A。
(float x, float y) B,
float theta)
{
float s = Math.Sin(theta);
float c = Math.Cos(theta);
// 將點移回原點。
B.x -= A.x。
B.y -= A.y。
// 將點順時針旋轉
float xnew = B.x * c - B.y * s;
float ynew = B.x * s B.y * c;
// 將點向后平移。
B.x = xnew A.x;
B.y = ynew A.y;
回傳B。
}
如果你想讓你的士兵平均分布在一個圓圈中,你需要計算每個士兵的旋轉角度,只需用float angle = 360 / numSoldiers;。
如果你的游戲是3D的,并且你在地板平面(XZ)上作業,你可以在代碼中用.ys改變.zs。
你也可以在一個簡單的unity專案立方體中或在一個控制臺的c#應用程式中檢查演算法是如何作業的,以了解它們,并檢查它們如何只是執行一個矢量的端點圍繞其原點的旋轉來回傳旋轉的點。我想這就是你需要找到你的士兵的位置的興趣點的原因。
uj5u.com熱心網友回復:
你可以從一些簡單的相對有序的位置分布開始,通過應用動態系統方法/梯度衰減式的迭代,你可以讓位置收斂到一個更有結構的模式。我在python中寫了這樣的實作,它是以矢量形式存在的,但我也添加了一個帶有for回圈的等效函式,以說明函式的結構。最后的有序模式的靈感來自于一群半徑相同的圓盤,如果它們被彈簧固定,會形成穩定的平衡位置,每兩個圓盤有一個。為了簡化計算,我對彈簧張力進行了平方處理,從而避免了平方根,所以并不完全像典型的物理模型,但接近于它。
import numpy as np
import matplotlib.pyplot as plt
def Grad(pos, r)。
Dq = - pos[:, :, np.newaxis] pos[:, np.newaxis, :] 。
D = Dq[0, :, :]*Dq[0, :, :] Dq[1, :, :]*Dq[1, :, :] np. identity(Dq.shape[1])
Dq = (1 - r**2 / D) * Dq
return - Dq.sum(axis=2)
def Grad_flow(q_, r, step) 。
Q = q_
n_iter = 0: Q = q_。
while True:
n_iter = n_iter 1 #你可以計算達到平衡所需的迭代次數。
Q_prev = Q
Q = Q - step * Grad(Q, r)
if np.sum(np.abs((Q.T).dot(Q) - (Q_prev.T).dot(Q_prev))< 1-5:
return Q
''
測驗。
''
p = np. array([[-3, 3], [-1, 3], [1,3], [3,3] 。
[-3, 1], [-1, 1] 。[1,1], [3,1] 。
[-3,-1], [-1,-1] 。[1,-1], [3,-1] 。
[-3,-3], [-1, -3] 。[1, -3], [3,-3] 。
[-2, 1], [-1,2] 。 [2,-2], [-2,-2] 。
[2,2], [2,0]]).T
r = 0.5 0.5
step=0.01。
q = Grad_flow(p, r, step)
''
繪圖。
''/span>
fig, axs = plt.subplots(1,1)
axs.set_aspect('equal')
axs.plot(q[0, :], q[1, :], 'ro'/span>)
axs.plot(p[0, :], p[1, :], 'bo')
plt.grid()
plt.show()
這是Grad函式的回圈版本:
def Grad(pos, r)。
grad = np.zeros(pos.shape, dtype=float)
for i in range(pos.shape[1] )。)
for j in range(pos.shape[1]) 。
if not i==j:
d_pos_0 = pos[0, i] - pos[0, j]
d_pos_1 = pos[1, i] - pos[1, j]
m = d_pos_0*d_pos_0 d_pos_1*d_pos_1
m = 1 - r*r / m
grad[0, i] = grad[0, i] m * d_pos_0
grad[1, i] = grad[1, i] m * d_pos_1
return grad
當然,所有這些都是啟發式的,我不能保證完全的通用性,所以你必須發揮和選擇引數r,這是位置之間的一半距離,迭代的步驟大小step,初始位置p等等。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/332587.html
標籤:

