sinuskurve c#


deen_90

Erfahrenes Mitglied
Hallo

Für die Schule muss ich eine Sinuskurve in einer Konsole anzeigen lassen. At the momentan hab ich überhaupt keinen Plan wie ich überhaupt anfangen soll.
Wäre nett wenn jemand mir helfen könnte.
 

Dario Linsky

Erfahrenes Mitglied
Hallo,

wenn ich dich richtig verstanden habe, ist die Aufgabe, in einer Konsole (Textfenster) eine Sinus-Funktion grafisch darzustellen?

Eine Sinus-Funktion verläuft entlang der x-Achse (von links nach rechts) und schwingt dabei immer zwischen Maximum und Minimum auf der y-Achse. Bei einer Textkonsole verläuft die Ausgabe allerdings von entlang der y-Achse (zeilenweise) und in jeder Zeile kann man den Cursor entlang der x-Achse verschieben... Du müsstest die Sinus-Kurve also zeilenweise zeichnen, das zu berechnen ist schon relativ aufwendig.

Wenn es allerdings nicht zwingend durch eine Berechnung umgesetzt werden soll, könntest du die Ausgabe ja z.B. als statisches ASCII-Art gestalten:

Code:
                |
   .-.          |  .-.
 ,´   `.        |,´   `.
'-------\-------/-------\-------,
         `.   ,'|        `.   ,'
           `-´  |          `-´
                |
Grüße, D.
 

Dario Linsky

Erfahrenes Mitglied
Hallo,

da hab ich mir so viel Mühe mit dem Bild gegeben und dann wird es nicht gebraucht... :( ;)

Gehen wir mal davon aus, dass die Kurve 10 Zeilen hoch sein soll und eine ganze Sinus-Periode abgebildet werden soll. Du iterierst also über die Zeilen und rückst in jeder den Cursor um eine Stelle nach rechts. Damit bekommst du den Abstand von rechts (x-Wert) und die Zeile (Position auf der y-Achse). Dann vergleichst du Math.Sin(x) mit dem y-Wert (gerundet, du hast ja nur ganze Zahlen) und bei Übereinstimmung setzt du an die aktuelle Cursorposition ein Zeichen.

Das machst du dann für jede Zeile. Wäre eine Möglichkeit, sowas zu zeichnen.

Grüße, D.
 

deen_90

Erfahrenes Mitglied
also ich weiss wie ich eine liniare funktion machen muss, irgendwie muss das auch mit em sinus funktionieren abr keine ahnung wie.


Code:
using System;
using System.Collections.Generic;
using System.Text;

namespace Parabel
{
    class Program
    {
        static void Main(string[] args)
        {
            int x;
            int y;

            Console.WriteLine("Parabel");
            Console.WriteLine("----------");
            Console.WriteLine();
            Console.WriteLine("Höhe?");
            y = int.Parse(Console.ReadLine());

            for (int i = y; i > 0; i--)
            {
                x = i*2;

                for (int j = x; j > 0; j--)
                {
                    if (j == 1)
                    {
                        Console.Write(".");
                        Console.WriteLine();
                    }
                    else
                    {
                        Console.Write(" ");
                    }
                }
            }

        }
    }
}
 

Dario Linsky

Erfahrenes Mitglied
Hi!

Ich hab dir mal kurz was runtergeschrieben:

C#:
static void Main(string[] args)
{
  Console.WriteLine("Sinus");
  Console.WriteLine("----------");
  Console.WriteLine();
  Console.Write("Höhe? ");

  int max = int.Parse(Console.ReadLine());

  for (int y = max; y >= -max; y--)
  {
    for (int x = 0; x < Math.Round(max * 2 * Math.PI, 0); x++)
    {
      if ((int) Math.Round(Math.Sin((double) x / max) * max) == y)
        Console.Write(":");
      else
        Console.Write(" ");
    }
    Console.WriteLine();
  }
  
}
Wichtig ist die Bedingung in der Schleife, damit nimmst du dir den gerundeten Wert vom Sinus der aktuellen Spalte und vergleichst, ob da die aktuelle Zeile vorliegt. Wenn das so ist, liegt diese Stelle auf der Sinuskurve und du gibst irgendein sichtbares Zeichen aus. Wenn nicht, gehst du weiter zur nächsten Spalte.

Weil eine Sinusperiode immer über eine Distanz von x bis x + 2 * PI geht, habe ich die Breite mal mit dementsprechend angesetzt (max * 2 * PI, gerundet), um eine vollständige Periode zu zeichnen.

Nebenbei: Das mit der Parabel funktioniert auch noch nicht so ganz, da kommt trotzdem immer eine Gerade raus.

Grüße, D.
 

Dario Linsky

Erfahrenes Mitglied
Hallo,

bei mir funktionierts nicht, er gibt mir einen fehler bei max und y
welche Fehlermeldung, welche Zeile? Bei mir lässt sich der Code ohne Probleme kompilieren.

Habe dir die Ausgabe auch noch etwas verschönert. ;)

C#:
using System;

class Program
{
  static void Main(string[] args)
  {
    Console.WriteLine("Sinus");
    Console.WriteLine("----------");
    Console.WriteLine();
    Console.Write("Höhe? ");
    
    int ymax = int.Parse(Console.ReadLine());
    int xmax = (int) Math.Round(ymax * 2 * Math.PI, 0);
    Console.WriteLine();
    
    for (int y = ymax; y >= -ymax; y--)
    {
      if (y == ymax)
        Console.Write(" 1  ");
      else if (y == 0)
        Console.Write(" 0  ");
      else if (y == -ymax)
        Console.Write("-1  ");
      else
        Console.Write("    ");
        
      for (int x = -xmax; x <= xmax; x++)
      {
        if ((int) Math.Round(Math.Sin((double) x / ymax) * ymax) == y)
          Console.Write(":");
        else if (x == 0)
          Console.Write("|");
        else
          if (y == 0)
            Console.Write("-");
          else
            Console.Write(" ");
      }
      Console.WriteLine();
    }
  } 
}
Am gleichmäßigsten sieht die Ausgabe aus, wenn du als Höhe 7 eingibst.

Grüße, D.
 

deen_90

Erfahrenes Mitglied
also ich habs jetzt wieder versucht und es gibt mir keinen Fehler mehr bei y=max.

jetzt hab ich noch eine Frage. Was bedeutet das genau: int xmax = (int) Math.Round(ymax * 2 * Math.PI, 0); ? was macht das, komm nicht so draus und das hier: if ((int) Math.Round(Math.Sin((double) x / ymax) * ymax) == y) ?
 
Zuletzt bearbeitet:

Dario Linsky

Erfahrenes Mitglied
Hi,

ein komplettes Sinus-Intervall erstreckt sich auf der x-Achse von 0 bis 2 * PI. Um das einigermaßen an der eingegebenen Höhe zu skalieren, multipliziere ich das noch mit dieser. Bei dem zweiten findet eine Überprüfung statt, ob die aktuelle Stelle von der Kurve geschnitten wird. Das ganze muss jeweils gerundet werden, da die Sinus-Funktion Double-Werte zurück liefert, auf der Konsole aber nur ganzzahlige "Koordinaten" zur Verfügung stehen.

Grüße, D.
 

MusicGrotesqueYT

Grünschnabel
Lass den User die Daten wie Amplitude, Verschiebungswinkel und Winkelgeschwindigkeit eingeben.

C#:
for (int i = 0; i < CanvasSinus.Width; i++)
            {
                Line lin = new Line();
                lin.Stroke = Brushes.Black;
                lin.X1 = i;
                lin.Y1 = CanvasSinus.Height / 2 - (Amplitude* Math.Sin(Winkelgeschwindigkeit* i + Verschiebungswinkel));
                lin.X2 = i + 1;
                lin.Y2 = CanvasSinus.Height / 2 - (Amplitude* Math.Sin(Winkelgeschwindigkeit* (i+1) + Verschiebungswinkel));
                CanvasSinus.Children.Add(lin);
            }