我一直在尋找解決方案,現在已經有很多元素可以使用,但不是真的如何將它們拼湊在一起。繪製船的二維蹤跡。 XNA
目標:爲玩家的船舶畫一條小徑。
到目前爲止:由於船的方向是不可預測的,我只有玩家船的以前的位置才能使用。爲了繪製軌跡,我可以簡單地在播放器的前一個位置繪製一個像素(或紋理),但這是昂貴的內存,並且不繪製曲線,它不會達到令人滿意的眼睛彎曲效果。
我一直在尋找Beziers Paths和Cathmull Rom的解決方案。
現在我可以得到給定點的控制點,然後從2點和2個控制點計算出一條曲線,從這裏我用一個點之間的距離製作一個VertexPositionColor數組,從曲線中製作一條triangleStrip。
這些是主要的功能我到目前爲止:
public Vector2[] GetControlPoints(Vector2 p0, Vector2 p1, Vector2 p2, float tension = 0.5f)
{
// get length of lines [p0-p1] and [p1-p2]
float d01 = Vector2.Distance(p0, p1);
float d12 = Vector2.Distance(p1, p2);
// calculate scaling factors as fractions of total
float sa = tension * d01/(d01 + d12);
float sb = tension * d12/(d01 + d12);
// left control point
float c1x = p1.X - sa * (p2.X - p0.X);
float c1y = p1.Y - sa * (p2.Y - p0.Y);
// right control point
float c2x = p1.X + sb * (p2.X - p0.X);
float c2y = p1.Y + sb * (p2.Y - p0.Y);
return new Vector2[] {new Vector2(c1x, c1y), new Vector2(c2x, c2y) };
}
// Given 2 points and 2 control points
public static VertexPositionColor[] bezierCurve(Vector2 start, Vector2 end, Vector2 c1, Vector2 c2)
{
VertexPositionColor[] points = new VertexPositionColor[SUBDIVISIONS + 2];
float fraction;
for (int i = 0; i < SUBDIVISIONS + 2; i++)
{
fraction = i * (1f/(float)SUBDIVISIONS);
points[i] = new VertexPositionColor(new Vector3((float)((start.X * Math.Pow((1 - fraction), 3))
+(c1.X * 3 * fraction * Math.Pow(1-fraction, 2))
+(c2.X * 3 * Math.Pow(fraction,2) * (1-fraction))
+(end.X * Math.Pow(fraction,3))),
(float)((start.Y * Math.Pow((1 - fraction), 3))
+ (c1.Y * 3 * fraction * Math.Pow(1 - fraction, 2))
+ (c2.Y * 3 * Math.Pow(fraction, 2) * (1 - fraction))
+ (end.Y * Math.Pow(fraction, 3))), 0), UNLIT);
}
return points;
}
/*
* This function treats the curve as a series of straight lines and calculates points on a line perpendicular to each point, resulting in two points THICKNESS appart.
* Requires THICKNESS to be set
*/
public static VertexPositionColor[] curveToStrip(VertexPositionColor[] curve)
{
VertexPositionColor[] strip = new VertexPositionColor[curve.Length * 2];
VertexPositionColor[] new1 = new VertexPositionColor[curve.Length];
VertexPositionColor[] new2 = new VertexPositionColor[curve.Length];
for (int i = 0; i < curve.Length; i++)
{
if (i < curve.Length-1)
{
Vector2 p1 = new Vector2(curve[i].Position.X, curve[i].Position.Y);
Vector2 p2 = new Vector2(curve[i + 1].Position.X, curve[i + 1].Position.Y);
Vector2 perpPoint = perpendicularPoint(p1, p2);
new1[i] = new VertexPositionColor(new Vector3(distanceToPoint(p1, perpPoint, THICKNESS/2), 0), UNLIT);
new2[i] = new VertexPositionColor(new Vector3(distanceToPoint(p1, perpPoint, -1 * THICKNESS/2), 0), UNLIT);
}
else
{
Vector2 p1 = new Vector2(curve[i].Position.X, curve[i].Position.Y);
Vector2 p2 = new Vector2(curve[i - 1].Position.X, curve[i - 1].Position.Y);
Vector2 perpPoint = perpendicularPoint(p1, p2);
new1[i] = new VertexPositionColor(new Vector3(distanceToPoint(p1, perpPoint, -1 * THICKNESS/2), 0), UNLIT);
new2[i] = new VertexPositionColor(new Vector3(distanceToPoint(p1, perpPoint, THICKNESS/2), 0), UNLIT);
}
}
我想過呼籲牌階段的功能,但是這似乎非常昂貴只是爲了一個小曲線,畫一個更大的貝濟耶路我想象它更糟。由於我在每一幀都會得到一個點,每個函數都會被調用來計算點之間的曲線,以繪製3個像素(或更少)的1條曲線。
我該怎麼辦?有什麼建議麼?
我還是這種東西的初學者!
這一切,我從幾個渠道獲得:
有趣的問題。出於好奇,你的船會留下什麼樣的蹤跡(煙霧,光線等)?如果是煙霧,那麼您可以在當前位置(每幀)部署n煙霧量,然後可以隨着時間的推移而逐漸消失,而無需Beziers Paths或Cathmull Rom。 – user3256944
@ user3256944是的,這是我一直在考慮的選擇之一。但是我希望這能起作用,如果過了一段時間,我不會嘗試一些其他的效果,比如你建議的煙霧效果不應該那麼難。我也想學習如何有效地與beziers和cathmull ROM使用三角形標籤:) – Joze