我是stackoverflow的新手,所以我希望我沒有打開一個已經被回答過的問題。
我想實作這種顯示一些物體的效果,就像在這個視頻上看到的那樣。
我能夠創建一個快速的樣本來模仿這種行為。我必須創建一個持續更新的表單,雖然我的方法很重,但我本可以用一個Timer來完成。
我使用System.Numerics來生成3D幾何圖形,并應用旋轉和視圖變換。
代碼
public partial class RunningForm1 。
{
float posAngle。
Queue<PointF> tail;
#region Windows API - User32.dll
[StructLayout(LayoutKind.Sequential)]
public struct WinMessage
{
public IntPtr hWnd;
public Message msg;
public IntPtr wParam;
public IntPtr lParam;
public uint time;
public System.Drawing.Point p;
}
[System.Security.SuppressUnmanagedCodeSecurity] //我們不會惡意使用這個。
[DllImport("User32.dll", CharSet=CharSet.Auto)]
static extern bool PeekMessage(out WinMessage msg, IntPtr hWnd, uint messageFilterMin, uint messageFilterMax, uint flags) ;
#endregion。
public RunningForm1()
{
InitializeComponent()。
//Initialize the machine[/span]。
posAngle = 0f;
tail = new Queue<PointF>()。
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e)。
pictureBox1.Paint = pic_Paint;
pictureBox1.SizeChanged = pic_SizeChanged;
MainLoop();
}
void UpdateMachine()
{
posAngle = 0.002f;
pictureBox1.Refresh()。
}
#region Main Loop
public void MainLoop()
{
// 鉤住應用程式的閑置事件。
System.Windows.Forms.Application.Idle = new EventHandler(OnApplicationIdle)。
//System.Windows.Forms.Application.Run(TrackForm);
}
private void OnApplicationIdle(>object sender, EventArgs e)。
{
while (AppStillIdle)
{
///在空閑時間(沒有訊息在等待)渲染一個框架。
UpdateMachine()。
}
}
private bool AppStillIdle
{
get
{
WinMessage msg;
return !PeekMessage(out msg, IntPtr.Zero, 0, 0)。
}
}
#endregion。
private void pic_SizeChanged(object sender, EventArgs e)。
{
pictureBox1.Refresh()。
}
private void pic_Paint(object sender, PaintEventArgs e)。
{
//顯示FPS計數器。
///繪制機器
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias。
var s = Math.Min(ClientSize.Width, ClientSize.Height) / 2f;
var view = Matrix4x4.CreatePerspective(1f, 1f, 1f, 10f) 。
view = Matrix4x4.Multiply(view, Matrix4x4.CreateTranslation(0, 0.24f, 0) )。
var q = Quaternion.CreateFromAxisAngle(Vector3.UnitY, posAngle)。
var pts = new Vector3[ ] {
new Vector3(s/2, 0, 0) 。
new Vector3(s/2, 20f, 0) 。
new Vector3(s/2, 20f, 18f),
new Vector3(s/2, -20f, 18f) 。
new Vector3(s/2, -40f, 18f) 。
new Vector3(s/2, -40f, -18f) 。
new Vector3(s/2, 20f, 18f)。
new Vector3(s/2, -20f, 0f) 。
};
for (int i = 0; i < pts.Length; i )
{
pts[i] = Vector3.Transform(pts[i], q);
pts[i] = Vector3.Transform(pts[i], view);
}
e.Graphics.TranslateTransform(ClientSize.Width / 2f, ClientSize.Height / 2f)。
using (var fill = new SolidBrush(Color.Gray))
{
foreach (var pt in tail.reverse()
{
e.Graphics.FillEllipse(fill, pt.X - 4, pt.Y - 4, 8, 8) 。
fill.Color = Color.FromArgb(Math.Max(0, fill.Color.A-1), fill.Color) 。
}
}
var px = pts.Select((p) => new PointF(p.X, p.Y)).ToArray() 。
e.Graphics.FillPolygon(SystemBrushes.ActiveCaption, px)。
e.Graphics.DrawPolygon(Pens.Black, px);
e.Graphics.FillEllipse(Brushes.Black, px[0].X - 4, px[0] 。 Y - 4, 8, 8)。)
tail.Enqueue(px[0] )。)
while (tail.Count >=255)
{
tail.Dequeue()。
}
}
我添加了一個tail物件,它可以畫出一個尾巴以獲得更好的運動效果。
uj5u.com熱心網友回復:
設定中心坐標為(CX, CY),場景半寬為R,垂直收縮率(垂直橢圓軸和水平軸的比率)為V。物件的數量是N
因此,你可以在圓上計算物體中心的坐標并進行垂直收縮。
角度 = 2 * Math.Pi / N Shift
X[i] = CX R * Cos(Angle)
Y[i] = CY V * R * Sin(Angle)
其中i是物件編號,Shift是旋轉木馬的引數(范圍為0...2*Pi)
也許為了準確定位,你必須添加-ObjWidth/2, -ObjHeight/2(如果你的繪圖功能采取左上角而不是中心)。
此外,為了提供適當的Z-order,你必須先根據角度范圍來繪制 "后方 "的物件。 角度范圍。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/319986.html
標籤:
