يتكون النواس البسيط من جسم صلب صغير الأبعاد (يمكن اعتباره نقطة مادية) معلق بطرف خيط غير قابل للامتداد وله كتلة مهملة، شد طرفه الآخر إلى حامل ثابت كما في الشكل:
لمحاكاة حركة النواس باستعمال لغة البرمجة دلفي نعتبر كرية صغيرة كتلتها مهملة معلقة بخيط طوله L مثبت في سقف ثابت ونترك الكرية حتى تستقر في وضعية معينة صانعة زاوية منعدمة مع الشاقول ومستقرة على بعد L من المبدأ، فتكون حينها خاضعة للجاذبية الأرضيةg=9.8 وتوتر الخيط T
نحرك الكرية حركة خفيفة فتصنع مع الشاقول زاويةθ0 ثم نتركها تتحرك بحرية فتكون معادلة تغير الزاوية كالتالي :
بالنسبة للاهتزازات الصغيرة يمكن أن نحصل على حل من الشكل التالي :
θ = θ0 cos ( ω0 t).
حيث:
ω0=√(g/L)
Sin(θ)=x/L ;
Cos(θ)=y/L ;
بعد الكرية على السقف يكون مساو للقيم التالية :
x=L*sin(θ) ;
y=L*cos(θ) ;
لجعل أبعاد الشاشة مناسبة للأبعاد الفيزيائية نقوم بالتحويلات التالية :
نعتبر المحور الشاقولي يمر من النقطة (0، 0، 0) للشاشة ويبعد السقف عن المركز بالمسافة b
حيث :
نضع :
h :=dummy1.height/2 ;
b :=L*h/200 ;
فتكون إحداثيات الكرة كالتالي
P.x := h * x/200;
P.y := -h * (l - y)/200;
P.z:=0;
Sphere1.Position.Point := P;
الفيديو التالي يعرض العناصر المستعملة في هذا التطبيف
وهذا نص الكود :
وهذا نص الكود :
unit Unit2; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms3D, FMX.Types3D, FMX.Forms, FMX.Graphics, FMX.Dialogs, System.Math.Vectors, FMX.MaterialSources, FMX.Objects3D, FMX.Controls3D, FMX.Layers3D, FMX.Ani, FMX.Controls.Presentation, FMX.StdCtrls, FMX.Edit, FMX.EditBox, FMX.SpinBox, FMX.ScrollBox, FMX.Memo; type TForm1 = class(TForm3D) Dummy1: TDummy; RoundCube1: TRoundCube; Light1: TLight; LightMaterialSource1: TLightMaterialSource; Sphere1: TSphere; TextureMaterialSource1: TTextureMaterialSource; FloatAnimation1: TFloatAnimation; Layer3D1: TLayer3D; Label1: TLabel; SpinBox1: TSpinBox; Label2: TLabel; LightMaterialSource2: TLightMaterialSource; Edit1: TEdit; Label3: TLabel; Plane1: TPlane; procedure Form3DCreate(Sender: TObject); procedure FloatAnimation1Process(Sender: TObject); procedure Dummy1Render(Sender: TObject; Context: TContext3D); procedure SpinBox1Change(Sender: TObject); procedure Sphere1Click(Sender: TObject); procedure Edit1Enter(Sender: TObject); procedure Edit1Exit(Sender: TObject); private { Déclarations privées } public { Déclarations publiques } end; var Form1: TForm1; t: single; w0, w, h, g, l, theta0, m: single; implementation {$R *.fmx} procedure TForm1.Dummy1Render(Sender: TObject; Context: TContext3D); var theta, x, y, b: single; P, ps, ps1: TPoint3d; begin theta := theta0 * cos(w0 * t); trystrtofloat(Edit1.Text, l); // ======================= x := l * sin(theta); y := l * cos(theta); if m < (l - y) then m := l - y; // 200*l/h b := h * l / 200; P.x := h * x/200; P.y := -h * (l - y)/200; Sphere1.Position.Point := P; ps := Dummy1.AbsoluteToLocal3D(RoundCube1.AbsolutePosition); ps1 := Dummy1.AbsoluteToLocal3D(Sphere1.AbsolutePosition); Context.DrawLine(ps, ps1, 1, TAlphacolors.yellow); Context.DrawLine(ps, point3d(ps.x, Dummy1.Height, ps.Z), 1, TAlphacolors.White); Label1.Text := format('X:%f,Y:%f ' + #13 + ' Z:%f Theta :%f ' + #13 + 'hmax:%f', [x, y, P.Z, 180 * theta / Pi, m]); end; procedure TForm1.Edit1Enter(Sender: TObject); begin FloatAnimation1.StopAtCurrent; end; procedure TForm1.Edit1Exit(Sender: TObject); begin t := 0; m := 0; FloatAnimation1.Start; end; procedure TForm1.FloatAnimation1Process(Sender: TObject); begin t := t + 0.05 end; procedure TForm1.Form3DCreate(Sender: TObject); begin t := 0; m := 0; g := 9.8; h := Dummy1.Height / 2; w := Dummy1.Width / 2; l := h / 2; theta0 := Pi / 4; SpinBox1.Value := theta0 * 180 / Pi; Edit1.Text := format('%f', [100 * l / h]); w0 := sqrt(g / l); t := 0; end; procedure TForm1.Sphere1Click(Sender: TObject); begin t := 0; m := 0; FloatAnimation1.Start; end; procedure TForm1.SpinBox1Change(Sender: TObject); begin theta0 := Pi * SpinBox1.Value / 180; end; end.// =======================