Forum: PC-Programmierung Sinus ausgeben lassen?


von Tobias Mehrl (Gast)


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:
1
#include<iostream>
2
#include<math.h>
3
#include<stdio.h>
4
using namespace std;
5
6
7
int main()
8
{
9
  int i, j;
10
  char array[21][41];
11
  double y_array[21];
12
13
  for(i=0; i<=20; i=i+1)    //array mit Leerzeichen füllen
14
  {
15
    for(j=0; j<=40; j=j+1)
16
    {
17
      array[i][j] = ' ';
18
      cout << array[i][j];
19
    }
20
  }
21
22
23
24
25
system("pause");
26
return 0;
27
}

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?

von qwertz (Gast)


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?

von Tobias Mehrl (Gast)


Lesenswert?

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

von Klaus W. (mfgkw)


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

von Klaus W. (mfgkw)


Lesenswert?

dto. M_PI in math.h für pi.

von Tobias Mehrl (Gast)


Lesenswert?

Hier ist mein Quellcode:
1
#include<iostream>
2
#include<math.h>
3
#include<stdio.h>
4
#include<stdlib.h>
5
using namespace std;
6
7
8
int main()
9
{
10
  int i, j;
11
  char array[21][41];
12
  int y_array[41];
13
14
  for(i=0; i<=20; i=i+1)        //array mit Leerzeichen füllen
15
  {
16
    for(j=0; j<=40; j=j+1)
17
    {
18
      array[i][j] = ' ';
19
    }
20
  }
21
22
23
  for(i=0; i<=40; i=i+1)
24
  {
25
    y_array[i] = 10*sin(i/(2*3.14159265))+10;
26
  }
27
28
29
system("pause");
30
return 0;
31
}

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?

von Klaus W. (mfgkw)


Lesenswert?

Tobias Mehrl schrieb:
> Ich hab in math.h weder M_PI

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

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

von Klaus W. (mfgkw)


Lesenswert?

Aus meiner math.h übrigens:
#define M_PI    3.14159265358979323846  /* pi */

von Klaus W. (mfgkw)


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

von Tobias Mehrl (Gast)


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?
1
#include<iostream>
2
#include<math.h>
3
#include<stdio.h>
4
#include<stdlib.h>
5
using namespace std;
6
7
8
int main()
9
{
10
  int i, j;
11
  char array[21][41];
12
13
  for(i=0; i<=20; i=i+1)        //array mit Leerzeichen füllen
14
  {
15
    for(j=0; j<=40; j=j+1)
16
    {
17
      array[i][j] = ' ';
18
    }
19
  }
20
21
22
23
24
  for(i=0; i<=20; i=i+1)        //array mit X füllen
25
  {
26
    for(j=0; j<=40; j=j+1)
27
    {
28
      array[int(10*sin(j/(2*3.14159265))+10)][j] = 'X';
29
    }
30
  }
31
32
33
34
  for(i=0; i<=20; i=i+1)
35
  {
36
    for(j=0; j<=40; j=j+1)
37
    {
38
      cout << array[i][j];
39
    }
40
  }
41
42
43
44
system("pause");
45
return 0;
46
}

von Tim T. (tim_taylor) Benutzerseite


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?

von Tobias Mehrl (Gast)


Lesenswert?

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

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Dann versuchs mal so:

#define _USE_MATH_DEFINES
#include <cmath>

und zwar auch in der Reihenfolge!

von Tobias Mehrl (Gast)


Lesenswert?

geht auch nicht...

von Klaus W. (mfgkw)


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++.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Tobias Mehrl schrieb:
> geht auch nicht...

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

Auszug aus cmath:
1
#ifdef _STD_USING
2
 #undef _STD_USING
3
  #include <math.h>
4
 #define _STD_USING
5
6
7
#else /* _STD_USING */
8
 #include <math.h>
9
#endif /* _STD_USING */


Auszug aus math.h:
1
#if defined(_USE_MATH_DEFINES) && !defined(_MATH_DEFINES_DEFINED)
2
#define _MATH_DEFINES_DEFINED
3
4
/* Define _USE_MATH_DEFINES before including math.h to expose these macro
5
 * definitions for common math constants.  These are placed under an #ifdef
6
 * since these commonly-defined names are not part of the C/C++ standards.
7
 */
8
9
/* Definitions of useful mathematical constants
10
 * M_E        - e
11
 * M_LOG2E    - log2(e)
12
 * M_LOG10E   - log10(e)
13
 * M_LN2      - ln(2)
14
 * M_LN10     - ln(10)
15
 * M_PI       - pi
16
 * M_PI_2     - pi/2
17
 * M_PI_4     - pi/4
18
 * M_1_PI     - 1/pi
19
 * M_2_PI     - 2/pi
20
 * M_2_SQRTPI - 2/sqrt(pi)
21
 * M_SQRT2    - sqrt(2)
22
 * M_SQRT1_2  - 1/sqrt(2)
23
 */
24
25
#define M_E        2.71828182845904523536
26
#define M_LOG2E    1.44269504088896340736
27
#define M_LOG10E   0.434294481903251827651
28
#define M_LN2      0.693147180559945309417
29
#define M_LN10     2.30258509299404568402
30
#define M_PI       3.14159265358979323846
31
#define M_PI_2     1.57079632679489661923
32
#define M_PI_4     0.785398163397448309616
33
#define M_1_PI     0.318309886183790671538
34
#define M_2_PI     0.636619772367581343076
35
#define M_2_SQRTPI 1.12837916709551257390
36
#define M_SQRT2    1.41421356237309504880
37
#define M_SQRT1_2  0.707106781186547524401
38
39
#endif  /* _USE_MATH_DEFINES */

von Tobias Mehrl (Gast)


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:
1
#include<iostream>
2
#include<math.h>
3
#include<stdio.h>
4
#include<stdlib.h>
5
using namespace std;
6
7
8
9
int main()
10
{
11
  int i, j;
12
  char array[21][41];
13
14
  for(i=0; i<=20; i=i+1)        //array mit Leerzeichen füllen
15
  {
16
    for(j=0; j<=40; j=j+1)
17
    {
18
      array[i][j] = ' ';
19
    }
20
  }
21
22
23
24
25
  for(i=0; i<=20; i=i+1)        //array mit X füllen
26
  {
27
    for(j=0; j<=40; j=j+1)
28
    {
29
      array[(10*sin(j/(2*3.14159265))+10),0][j] = 'X';
30
    }
31
  }
32
33
34
35
  for(i=0; i<=20; i=i+1)
36
  {
37
    for(j=0; j<=40; j=j+1)
38
    {
39
      cout << array[i][j];
40
    }
41
  }
42
43
44
45
system("pause");
46
return 0;
47
}

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!

von Sam .. (sam1994)


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:
1
#define round(a) ((int)((double)(a) + 0.5))

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Dann nehm ich dir mal das Denken ab:
1
#include <iostream>
2
#define _USE_MATH_DEFINES
3
#include <cmath>
4
5
using namespace std;
6
7
double round( double x ) {
8
 return floor( x + 0.5 );
9
}
10
11
int main( void ) {
12
 int i, j;
13
 char array[21][41];
14
15
 for( i = 0; i <= 20; i++ )        //array mit Leerzeichen füllen
16
  for( j = 0; j <= 40; j++ )
17
   array[i][j] = ' ';
18
19
 for( i = 0; i <= 20; i++ )        //array mit X füllen
20
  array[i][ (int) round(10 * sin( i / ( 2 * M_PI ) ) + 10)] = 'X';
21
22
 for( i = 0; i <= 20; i = i++ ) {
23
  for( j = 0; j <= 40; j = j++ ) cout << array[i][j];
24
  cout << endl;
25
 }
26
27
 system("pause");
28
 
29
 return 0;
30
}

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

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Samuel K. schrieb:

> Noch was zum runden: Das kann man auch gut selber schreiben:
>
1
#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!

von Tobias Mehrl (Gast)


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?
1
  for(i=0; i<=40; i=i+1)        //Ausgabe
2
  {
3
    for(j=0; j<=20; j=j+1)
4
    {
5
      cout << array[j][i];
6
    }
7
  cout << endl;
8
  }

von Sam .. (sam1994)


Lesenswert?

Stimmt, da hab ich nicht drangedacht.

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

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

PS: hier hätte sogar pos_round gereicht.

von Frickler (Gast)


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.

von Tim T. (tim_taylor) Benutzerseite


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';

von Sam .. (sam1994)


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.

von Tobias Mehrl (Gast)


Lesenswert?

Damn! Jetzt hab ich zwar eine Sinuskurve, aber mit einer 
Phasenverschiebung. Die erste Halbwelle darf nicht unten beginnen 
sondern oben! Mein Code:
1
  for(i=0; i<=20; i=i+1)        //array mit X füllen
2
  {
3
      array[(int)(10*sin(i/(2*3.14159265))+10)][i] = 'X';
4
  }
5
  for(i=20; i<=40; i=i+1)
6
  {
7
      array[(int)(10*sin(i/(2*3.14159265))+10)][i] = 'X';
8
  }
9
  
10
11
12
13
  for(i=0; i<=20; i=i+1)        //Ausgabe
14
  {
15
    for(j=0; j<=40; j=j+1)
16
    {
17
      cout << array[i][j];
18
    }
19
  cout << endl;
20
  }

von Klaus W. (mfgkw)


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).

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

seufz

-sin

von Tobias Mehrl (Gast)


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!

von Tobias Mehrl (Gast)


Lesenswert?

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

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Dann kann ich jetzt ja mal Posten wie es besser aussieht:
1
#include <iostream>
2
#define _USE_MATH_DEFINES
3
#include <cmath>
4
5
// Wenn tatsächlich M_PI bei dir nicht definiert sein sollte:
6
#ifndef M_PI
7
#define M_PI 3.14159265358979323846
8
#endif
9
10
using namespace std;
11
12
const unsigned int ZEILEN  = 21;
13
const unsigned int SPALTEN = 41;
14
15
int my_round( double x ) {
16
 return ( int ) floor( x + 0.5 );
17
}
18
19
int main( void ) {
20
 int x, y;
21
 char array[ ZEILEN ][ SPALTEN ];
22
23
 for( y = 0; y < ZEILEN; y++ )        //array mit Leerzeichen füllen
24
  for( x = 0; x < SPALTEN; x++ )
25
   array[ y ][ x ] = ' ';
26
27
 for( x = 0; x < SPALTEN; x++ )        //array mit X füllen
28
  array[ my_round( 10 * -sin( x / ( 2 * M_PI ) ) + 10 ) ][ x ] = 'X';
29
30
 for( y = 0; y < ZEILEN; y = y++ ) {
31
  for( x = 0; x < SPALTEN; x = x++ ) cout << array[ y ][ x ];
32
  cout << endl;
33
 }
34
35
 return 0;
36
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.