mikrocontroller.net

Forum: PC-Programmierung Sinus ausgeben lassen?


Autor: Tobias Mehrl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi leute!

Ich soll mir einen Sinus ausgeben lassen. Ich soll mit einem Array mit 
21 Zeilen à 41 Spalten arbeiten. Meinen ersten Ansatz seht ihr da:
#include<iostream>
#include<math.h>
#include<stdio.h>
using namespace std;


int main()
{
  int i, j;
  char array[21][41];
  double y_array[21];

  for(i=0; i<=20; i=i+1)    //array mit Leerzeichen füllen
  {
    for(j=0; j<=40; j=j+1)
    {
      array[i][j] = ' ';
      cout << array[i][j];
    }
  }




system("pause");
return 0;
}

Ich hab mir jetzt mein array mit Leerzeichen auffüllen lassen. Ich weiß 
jetzt allerdings nicht mehr weiter. Ich muss mir ja jetzt quasi in mein 
Array nur an bestimmen Stellen ein X schreiben lassen. Diese Stellen an 
denen das X reinkommt unterliegen ja dieser Sinusfunktion: 
y=10*sin(i/(2*PI))+10.

Wie gehts da jetzt weiter? Ich zerbrech mir da jetzt schon seit Stunden 
den Kopf darüber!

Könnt ihr mir helfen?

Autor: qwertz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast doch quasi ein Bild mit 41x21 Pixeln, wobei du in jeder Spalte 
genau ein "Pixel" setzen musst... Also für jede Spalte den y-WErt 
berechnen und das passende "Pixel" auf "X" setzen...
achja, die funktion "round" hilft dir vielleicht noch?

Autor: Tobias Mehrl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In welcher Bibliothek ist eigentlich die Konstante für Pi und wo ist 
round() drin?

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
math.h ist ein heißer Kandidat für alle Mathe-Funktionen.
round() gibt es aber dort erst seit ISO-C99, k.A. ob MS das
kennt - müsstest du in deiner Doku nachsehen.

Unter liux steht es bei
   man round

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dto. M_PI in math.h für pi.

Autor: Tobias Mehrl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier ist mein Quellcode:
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
using namespace std;


int main()
{
  int i, j;
  char array[21][41];
  int y_array[41];

  for(i=0; i<=20; i=i+1)        //array mit Leerzeichen füllen
  {
    for(j=0; j<=40; j=j+1)
    {
      array[i][j] = ' ';
    }
  }


  for(i=0; i<=40; i=i+1)
  {
    y_array[i] = 10*sin(i/(2*3.14159265))+10;
  }


system("pause");
return 0;
}

Ich hab in math.h weder M_PI noch round() drin. Ich hab mir jetzt mit 
ner Typumwandlung nach int "runden" lassen. Wie geht's an der Stelle 
jetzt weiter? Könnt ihr mir helfen?

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tobias Mehrl schrieb:
> Ich hab in math.h weder M_PI

Dann halt
#define PI   3.1415926354 // mehr Stellen müsstest du selber nachschlagen

Tobias Mehrl schrieb:
> noch round() drin.
double round( double x )
{
   return floor( x + 0.5 );
}

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aus meiner math.h übrigens:
#define M_PI    3.14159265358979323846  /* pi */

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tobias Mehrl schrieb:
> Wie geht's an der Stelle
> jetzt weiter?

Dann musst du dich entscheiden:
- ob die erste Felddimension das x sein soll und die zweite
  das y bz. sin(x), oder umgekehrt
- Überlegen, wie weit der Definitionsbereich gehen soll
  (die x, v... bis ...)
- entsprechend überlegen, welches x zu welchem Feldindex gehört
  oder umgekehrt welcher Feldindex welchem x entspricht
- analog den Wertebereich ermitteln (y geht von... bis...)
- wieder überlegen, welches y welchem Feldindex entspricht
  (jetzt in der anderen Richtung des Feldes)
- dann x von... bis... laufen lassen und die zugehörigen
  y im Feld bei [i_x][i_y] oder [i_y][i_x] eintragen
- dann das Feld ausgeben

Autor: Tobias Mehrl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, Leute!

Aber ich finde weder round noch pi. Ich würd jetzt mal vorschlagen ich 
schreib von hand in die rechnung rein und lasse mit int runden. Leider 
funktioniert mein programm immer noch nicht. Könnt ihr mir vielleicht 
sagen ob ich auf dem richtigen Weg bin oder auf dem totalen holzweg?
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
using namespace std;


int main()
{
  int i, j;
  char array[21][41];

  for(i=0; i<=20; i=i+1)        //array mit Leerzeichen füllen
  {
    for(j=0; j<=40; j=j+1)
    {
      array[i][j] = ' ';
    }
  }




  for(i=0; i<=20; i=i+1)        //array mit X füllen
  {
    for(j=0; j<=40; j=j+1)
    {
      array[int(10*sin(j/(2*3.14159265))+10)][j] = 'X';
    }
  }



  for(i=0; i<=20; i=i+1)
  {
    for(j=0; j<=40; j=j+1)
    {
      cout << array[i][j];
    }
  }



system("pause");
return 0;
}

Autor: Tim T. (tim_taylor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich fragte mich immer wieder warum Leute C++ programmieren und die C 
Includes benutzen...


<iostream> -> Hierfür wohl kein C-Include gefunden oder wie?
<math.h> -> <cmath>
<stdio.h> -> <cstdio>
<stdlib.h> -> <cstdlib>

Denke das Prinzip sollte klar sein...


Ansonsten, womit programmierst du?

Autor: Tobias Mehrl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich programmiere mit Visual Studio 2010. Und auch dein Vorschlag 
funktioniert weder für round, noch für M_PI...

Autor: Tim T. (tim_taylor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann versuchs mal so:

#define _USE_MATH_DEFINES
#include <cmath>

und zwar auch in der Reihenfolge!

Autor: Tobias Mehrl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
geht auch nicht...

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann schreib dir pi und round doch selbst; siehe oben!

Die Funktion floor() gibt es auf jeden Fall in deiner math.h,
versprochen!

Und wie Tim schon sagte: entscheide dich mal, ob C oder C++.

Autor: Tim T. (tim_taylor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tobias Mehrl schrieb:
> geht auch nicht...

Doch tut es! Zumindest für M_PI
Und floor esxistiert ebenfalls!

Auszug aus cmath:
#ifdef _STD_USING
 #undef _STD_USING
  #include <math.h>
 #define _STD_USING


#else /* _STD_USING */
 #include <math.h>
#endif /* _STD_USING */


Auszug aus math.h:
#if defined(_USE_MATH_DEFINES) && !defined(_MATH_DEFINES_DEFINED)
#define _MATH_DEFINES_DEFINED

/* Define _USE_MATH_DEFINES before including math.h to expose these macro
 * definitions for common math constants.  These are placed under an #ifdef
 * since these commonly-defined names are not part of the C/C++ standards.
 */

/* Definitions of useful mathematical constants
 * M_E        - e
 * M_LOG2E    - log2(e)
 * M_LOG10E   - log10(e)
 * M_LN2      - ln(2)
 * M_LN10     - ln(10)
 * M_PI       - pi
 * M_PI_2     - pi/2
 * M_PI_4     - pi/4
 * M_1_PI     - 1/pi
 * M_2_PI     - 2/pi
 * M_2_SQRTPI - 2/sqrt(pi)
 * M_SQRT2    - sqrt(2)
 * M_SQRT1_2  - 1/sqrt(2)
 */

#define M_E        2.71828182845904523536
#define M_LOG2E    1.44269504088896340736
#define M_LOG10E   0.434294481903251827651
#define M_LN2      0.693147180559945309417
#define M_LN10     2.30258509299404568402
#define M_PI       3.14159265358979323846
#define M_PI_2     1.57079632679489661923
#define M_PI_4     0.785398163397448309616
#define M_1_PI     0.318309886183790671538
#define M_2_PI     0.636619772367581343076
#define M_2_SQRTPI 1.12837916709551257390
#define M_SQRT2    1.41421356237309504880
#define M_SQRT1_2  0.707106781186547524401

#endif  /* _USE_MATH_DEFINES */

Autor: Tobias Mehrl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
floor() rundet mir ja immer ab; ich finde das ist genauso schlecht wie 
Stellen abschneiden. Ich bleibe gleich bei der "int-Rundung". Das PI geb 
ich mir als Zahl vor. Das kann man später auch noch verbessern. Ich hab 
aber immer noch größere Probleme mit meinem nicht funktionierenden Code. 
Der sieht jetzt so aus:
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
using namespace std;



int main()
{
  int i, j;
  char array[21][41];

  for(i=0; i<=20; i=i+1)        //array mit Leerzeichen füllen
  {
    for(j=0; j<=40; j=j+1)
    {
      array[i][j] = ' ';
    }
  }




  for(i=0; i<=20; i=i+1)        //array mit X füllen
  {
    for(j=0; j<=40; j=j+1)
    {
      array[(10*sin(j/(2*3.14159265))+10),0][j] = 'X';
    }
  }



  for(i=0; i<=20; i=i+1)
  {
    for(j=0; j<=40; j=j+1)
    {
      cout << array[i][j];
    }
  }



system("pause");
return 0;
}

Die erste Felddim. ist mein Wertebereich der von 0-20 geht. Die zweite 
Felddim. ist meine Definitionsbereich der von 0-40 geht. Jetzt muss ich 
irgendwie in Abhängigkeit von meiner Berechnung der y-Werte in mein 
array schreiben und danach ausgeben. Da komm ich nicht weiter. Wenn ich 
das Programm so kompiliere wie's momentan ist, dann bekomm ich zwar ne 
Ausgabe, aber das ist alles andere nur kein Sinus!

Autor: Sam .. (sam1994)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tobias Mehrl schrieb:
> for(i=0; i<=20; i=i+1)        //array mit X füllen
>   {

Das muss weg. Du gehst jeden x wert durch und errechnest den Sin.


Noch was zum runden: Das kann man auch gut selber schreiben:
#define round(a) ((int)((double)(a) + 0.5))

Autor: Tim T. (tim_taylor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann nehm ich dir mal das Denken ab:
#include <iostream>
#define _USE_MATH_DEFINES
#include <cmath>

using namespace std;

double round( double x ) {
 return floor( x + 0.5 );
}

int main( void ) {
 int i, j;
 char array[21][41];

 for( i = 0; i <= 20; i++ )        //array mit Leerzeichen füllen
  for( j = 0; j <= 40; j++ )
   array[i][j] = ' ';

 for( i = 0; i <= 20; i++ )        //array mit X füllen
  array[i][ (int) round(10 * sin( i / ( 2 * M_PI ) ) + 10)] = 'X';

 for( i = 0; i <= 20; i = i++ ) {
  for( j = 0; j <= 40; j = j++ ) cout << array[i][j];
  cout << endl;
 }

 system("pause");
 
 return 0;
}

Kompiliert mit VS2008 Professional als Win32 C++ Konsolenanwendung ohne 
Fehler oder Warnungen und gibt eine Sinushalbwelle Senkrecht aus.

Autor: Tim T. (tim_taylor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Samuel K. schrieb:

> Noch was zum runden: Das kann man auch gut selber schreiben:
>
#define round(a) ((int)((double)(a) + 0.5))

Also ist -1.0 gerundet 0, danke für die Info...

Prinzipiell bin ich auch für sowas zu haben, man muss aber immer auf 
Nebeneffekte achten!

Autor: Tobias Mehrl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit dem Code hier gebe ich jetzt die zweite Sinushalbwelle aus. Wie aber 
kann ich jetzt noch die erste nach oben schwingende Sinushalbwelle 
erzeugen?
  for(i=0; i<=40; i=i+1)        //Ausgabe
  {
    for(j=0; j<=20; j=j+1)
    {
      cout << array[j][i];
    }
  cout << endl;
  }

Autor: Sam .. (sam1994)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt, da hab ich nicht drangedacht.

Dann halt so:
#define round(a) ((int)((double)floor(a) + 0.5))

oder so:
#define pos_round(a) ((int)((double)(a) + 0.5))
#define neg_round(a) ((int)((double)(a) - 0.5))
#define round(a) ((a)<0?neg_round(a):pos_round(a))

PS: hier hätte sogar pos_round gereicht.

Autor: Frickler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und gleich angewöhnen, keine 'magischen' Konstanten in Programmen zu 
verwenden:

#define DIMX 41
#define DIMY 21

und dann im Code alle Stellen mit 20/21/40/41 entsprechend korrigieren.

Oder wenn schon C++, dann gleich

const int DIMX = 41;
const int DIMY = 21;


Und wenn Du statt i und j, beispielsweise ix und iy nimmst, kommt man 
auch mit den Zeilen/Spalten nicht so durcheinander.

Autor: Tim T. (tim_taylor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast einen Denkfehler drin, dreh die Sinuswelle um 90 Grad gegen den 
Uhrzeigersinn und deine Frage erledigt sich von selbst...

Tip, hier dran drehen:

 for( i = 0; i <= 20; i++ )        //array mit X füllen
  array[i][ (int) round(10 * sin( i / ( 2 * M_PI ) ) + 10)] = 'X';

Autor: Sam .. (sam1994)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frickler schrieb:
> Und gleich angewöhnen, keine 'magischen' Konstanten in Programmen zu
> verwenden:
>
> #define DIMX 41
> #define DIMY 21
>
> und dann im Code alle Stellen mit 20/21/40/41 entsprechend korrigieren.
>
> Oder wenn schon C++, dann gleich
>
> const int DIMX = 41;
> const int DIMY = 21;

Was soll an den #define schlecht sein? Ich verwende const nur in c# da 
es da keine #define gibt. Bisher bin ich immer damit gut gefahren.

Autor: Tobias Mehrl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Damn! Jetzt hab ich zwar eine Sinuskurve, aber mit einer 
Phasenverschiebung. Die erste Halbwelle darf nicht unten beginnen 
sondern oben! Mein Code:
  for(i=0; i<=20; i=i+1)        //array mit X füllen
  {
      array[(int)(10*sin(i/(2*3.14159265))+10)][i] = 'X';
  }
  for(i=20; i<=40; i=i+1)
  {
      array[(int)(10*sin(i/(2*3.14159265))+10)][i] = 'X';
  }
  



  for(i=0; i<=20; i=i+1)        //Ausgabe
  {
    for(j=0; j<=40; j=j+1)
    {
      cout << array[i][j];
    }
  cout << endl;
  }

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Samuel K. schrieb:
> Was soll an den #define schlecht sein?

z.B. daß sie in maximal einer Übersetzungseinheit zwangsweise
gleich sind (und genau genommen nicht mal da).

Autor: Tim T. (tim_taylor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
seufz

-sin

Autor: Tobias Mehrl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Tim T.:

Du schreibst ja, ich soll die Sinushalbwelle 90 Grad gegen den 
Uhrzeigersinn drehen. Wenn ich jetzt mit meinem obigen Code 
weiterarbeiten möchte, müsste die komplette Sinuswelle auf der 
Mittelachse quasi um 180 flippen, wenn du verstehst was ich mein!

Autor: Tobias Mehrl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke etz gehts! Grade in dem Augenblick wo du's geschrieben hast is mir 
eingefallen! danke an euch

Autor: Tim T. (tim_taylor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann kann ich jetzt ja mal Posten wie es besser aussieht:
#include <iostream>
#define _USE_MATH_DEFINES
#include <cmath>

// Wenn tatsächlich M_PI bei dir nicht definiert sein sollte:
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

using namespace std;

const unsigned int ZEILEN  = 21;
const unsigned int SPALTEN = 41;

int my_round( double x ) {
 return ( int ) floor( x + 0.5 );
}

int main( void ) {
 int x, y;
 char array[ ZEILEN ][ SPALTEN ];

 for( y = 0; y < ZEILEN; y++ )        //array mit Leerzeichen füllen
  for( x = 0; x < SPALTEN; x++ )
   array[ y ][ x ] = ' ';

 for( x = 0; x < SPALTEN; x++ )        //array mit X füllen
  array[ my_round( 10 * -sin( x / ( 2 * M_PI ) ) + 10 ) ][ x ] = 'X';

 for( y = 0; y < ZEILEN; y = y++ ) {
  for( x = 0; x < SPALTEN; x = x++ ) cout << array[ y ][ x ];
  cout << endl;
 }

 return 0;
}

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.