Hallo alle zusammen.
Wir haben beute im Physik-Seminar unter anderem über sog. Lissajous-Figuren gesprochen und auch ein paar mit dem Oszilloskop und Frequenzgeneratoren erzeugt.
Ich fand die Dinger interessant und hab mich gefragt, ob ich die nicht auch am Computer "erzeugen" kann. Der Plan ist, ich geb zwei Frequenzen an und mir wird die zugehörige Figur gezeichnet. Durch etwas Recherche hab ichs jetzt auch schon hinbekommen, dass die korrekten Figuren entstehen, allerdings bewegen sie sich nicht sondern sind starr. Ich hätte es aber gerne so, dass sie sich wie am Oszilloskop bewegen (siehe auch Bild auf Wikipedia). Scheinbar plotten alle Codes aus dem Internet nur die statischen Figuren, und da ich mich in dem Gebiet nicht wirklich auskenne, hab ich da keinen Ansatz.
Mein Code sieht momentan so aus:
Spoiler anzeigen
Was fehlt, damit sich die Figuren bewegen? Oder ist das ein ganz und gar falscher Ansatz?
Außerdem bin ich mir nicht sicher, wie ich effektiv bestimmen kann, welche berechneten Punkte ich behalten kann/muss. Momentan nehme ich da einfach ne feste Zeit (Zeile 75), aber ich glaube das ist der falsche Weg. Wie geht es richtig?
Wir haben beute im Physik-Seminar unter anderem über sog. Lissajous-Figuren gesprochen und auch ein paar mit dem Oszilloskop und Frequenzgeneratoren erzeugt.
Ich fand die Dinger interessant und hab mich gefragt, ob ich die nicht auch am Computer "erzeugen" kann. Der Plan ist, ich geb zwei Frequenzen an und mir wird die zugehörige Figur gezeichnet. Durch etwas Recherche hab ichs jetzt auch schon hinbekommen, dass die korrekten Figuren entstehen, allerdings bewegen sie sich nicht sondern sind starr. Ich hätte es aber gerne so, dass sie sich wie am Oszilloskop bewegen (siehe auch Bild auf Wikipedia). Scheinbar plotten alle Codes aus dem Internet nur die statischen Figuren, und da ich mich in dem Gebiet nicht wirklich auskenne, hab ich da keinen Ansatz.
Mein Code sieht momentan so aus:
C#-Quellcode
- public class LissajousPlotter : Control
- {
- private struct PlottetPoint
- {
- public PointF Point;
- public double Time;
- }
- readonly List<PlottetPoint> plottedPoints;
- readonly object locker;
- Thread updateThread;
- bool loopRunning;
- public double Frequency1 { get; set; }
- public double Frequency2 { get; set; }
- public LissajousPlotter()
- {
- SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint, true);
- SetStyle(ControlStyles.ResizeRedraw, true);
- UpdateStyles();
- plottedPoints = new List<PlottetPoint>();
- loopRunning = false;
- locker = new object();
- }
- public void Start()
- {
- if (!loopRunning)
- {
- loopRunning = true;
- updateThread = new Thread(UpdateLoop);
- updateThread.IsBackground = true;
- updateThread.Start();
- }
- }
- public void Stop()
- {
- if (loopRunning)
- {
- loopRunning = false;
- updateThread.Join();
- plottedPoints.Clear();
- }
- }
- private static PlottetPoint Plot(double frequency1, double frequency2, double t)
- {
- float x = (float)Math.Sin(frequency1 * t);
- float y = (float)Math.Sin(frequency2 * t);
- return new PlottetPoint() { Point = new PointF(x, y), Time = t };
- }
- private void UpdateLoop()
- {
- var invalidateAction = new Action(Invalidate);
- var sw = new Stopwatch();
- sw.Start();
- while (loopRunning)
- {
- PlottetPoint p = Plot(Frequency1, Frequency2, sw.ElapsedMilliseconds / 1000.0);
- lock (locker)
- {
- plottedPoints.Add(p);
- for (int i = 0; i < plottedPoints.Count; i++)
- {
- if (plottedPoints[i].Time >= p.Time - 0.2)
- {
- plottedPoints.RemoveRange(0, i);
- break;
- }
- }
- }
- BeginInvoke(invalidateAction);
- Thread.Sleep(1);
- }
- sw.Stop();
- }
- protected override void OnPaint(PaintEventArgs e)
- {
- var g = e.Graphics;
- g.SmoothingMode = SmoothingMode.AntiAlias;
- g.PixelOffsetMode = PixelOffsetMode.HighQuality;
- PointF[] points;
- lock (locker) points = plottedPoints.Select(p => p.Point).ToArray();
- if (points.Length == 0)
- return;
- using (var matrix = new Matrix())
- {
- matrix.Translate(Width / 2.0f, Height / 2.0f);
- float scale = Math.Min(Width / 4.0f, Height / 4.0f);
- matrix.Scale(scale, -scale);
- g.Transform = matrix;
- using (var pen = new Pen(Color.Lime, 0.02f))
- g.DrawLines(pen, points);
- g.ResetTransform();
- }
- }
- }
Außerdem bin ich mir nicht sicher, wie ich effektiv bestimmen kann, welche berechneten Punkte ich behalten kann/muss. Momentan nehme ich da einfach ne feste Zeit (Zeile 75), aber ich glaube das ist der falsche Weg. Wie geht es richtig?