Task
Your task is to write a program that will draw graphs and output them as coloured image in
the .ppm file format and display them using a suitable external image viewer (IrfanView).
The program will use code generated sine waves, and harmonics of these, to calculate and
display the harmonic components of a square wave.

All sine wave harmonic should be displayed, each in a different colour – and the square
wave that results from summing all the sine waves should also be displayed.
The resultant waveforms should be output as a single file in the .ppm format. Initially,
assume an image 256 pixels wide by 128 pixels high with a colour depth of 8 bits for each
channel. There should be two full cycles of the waveform under construction across the
width of the image. The background colour should be black, and any axes or labels you add
should be in white. Check the resulting file, using the image viewer IrfanView. A sample of
output for 5 harmonics is given at the top of this assignment
Design a user interface allowing the user to specify the number of harmonic components to
use. The user should also be able to re-run the calculation without exiting the program.
The code containing your main() function should be in a file called wsa010cwk.c
Any functions you write can be in the same file as main, but can also be implemented in a
separate C source file in your project, called functions.c. You will need to write a
prototypes file, functions.h which should be #included at the top of
functions.c and wsa010cwk.c

Deliverables
Files :

  • Source files wsa010cwk.c and if used functions.c, functions.h,
  • Executable file wsa010cwk.exe.

Recommended Answers

All 27 Replies

This is what I have so far. I'm stuck on generating the waveform.

functions file

#define _CRT_SECURE_NO_WARNINGS
#include "prototype.h"

void imgwrite()
{
    FILE *imgfile = NULL; // File pointer
    int x, y;

    imgfile = fopen("waveform.ppm", "w"); // Create file and write

    if (imgfile == NULL)
    {
        printf("Error creating the file");
        return;
    }

    fprintf(imgfile, "%s", "P3\n");
    fprintf(imgfile, "%s", "# waveform.ppm\n");
    fprintf(imgfile, "%d %d\n", W, H);
    fprintf(imgfile, "%d\n", D);

    for (y = 0; y < H; y++) //pixel data height
    {
        for (x = 0; x < W; x++) //pixel data width
        {
            fprintf(imgfile, "%d %d %d\t", rgb_data[y][x][0], rgb_data[y][x][1], rgb_data[y][x][2]);
        }
        fprintf(imgfile, "\n");
    }
    fclose(imgfile);
}

main code

#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include "prototype.h"

void main(void)
{
    int clr1 = 0, clr2 = 0, clr3 = 0, clr4 = 255;
    int f, x, y;

    for (y = 0; y < H; ++y) //pixel data height
    {
        for (x = 0; x < W; ++x) //pixel data width
        {
            rgb_data[y][x][0] = clr1;
            rgb_data[y][x][1] = clr2;
            rgb_data[y][x][2] = clr3;
        }
    }

    for (x = 0; x < W; ++x)             //top border
    {
        y = 0;
        rgb_data[y][x][0] = clr4;
        rgb_data[y][x][1] = clr4;
        rgb_data[y][x][2] = clr4;
    }

    for (x = 0; x < W; ++x)             //bottom border
    {
        y = H - 1;
        rgb_data[y][x][0] = clr4;
        rgb_data[y][x][1] = clr4;
        rgb_data[y][x][2] = clr4;
    }

    for (x = 0; x < W; ++x)             //x-axis
    {
        y = H / 2;
        rgb_data[y][x][0] = clr4;
        rgb_data[y][x][1] = clr4;
        rgb_data[y][x][2] = clr4;
    }

    for (y = 0; y < H; ++y)             //left border
    {
        x = 0;
        rgb_data[y][x][0] = clr4;
        rgb_data[y][x][1] = clr4;
        rgb_data[y][x][2] = clr4;
    }

    for (y = 0; y < H; ++y)             //right border
    {
        x = W - 1;
        rgb_data[y][x][0] = clr4;
        rgb_data[y][x][1] = clr4;
        rgb_data[y][x][2] = clr4;
    }

    /*Sine and square waves*/

    for (x = 0; x < W; ++x)
    {
        y = ((H - 1) / 2 + (H - 1) / 2 * sin(1 * x / W * 2 * pi));
        rgb_data[y][x][0] = clr1;
        rgb_data[y][x][1] = clr4;
        rgb_data[y][x][2] = clr3;
    }

    imgwrite();
    system("waveform.ppm");
    scanf("%*s");
}

header file

#include <stdio.h>
#include <math.h>

#define H 1440
#define W 2560
#define D 255
#define pi 3.141592653

int rgb_data[H][W][3];

void imgwrite();

I'll take this is a task and not homework. So my research would be as follows.

  1. https://www.google.com/search?q=write+ppm+file+c%2B%2B
  2. From 1, I see a favorite site ROSETTACODE. That's https://rosettacode.org/wiki/Bitmap/Write_a_PPM_file
  3. I might skip a direct write to PPM and consider scripting my data to GNUPLOT which would open the door to a lot more options.

Again, I take this is not homework so we can use other solutions and code from the web.

I'm actually looking at how I can generate a sine wave, as I have already made the .ppm file working.

That would be in psuedo code about 2 lines of code.

for (float x = 0.00; x < 1.00; x += 0.01) {
    cout << sin(x) << endl;
}

Adjust 1.00 and step value as required.

May I ask, how does this help me out in generating a sine wave?
I'm mainly using C for my code.

waveform.jpg

This is what I have as of now, with the code that I gave

Is this not a sine function?

for (x = 0; x < W; ++x)
    {
        y = ((H - 1) / 2 + (H - 1) / 2 * sin(1 * x / W * 2 * pi));
        rgb_data[y][x][0] = clr1;
        rgb_data[y][x][1] = clr4;
        rgb_data[y][x][2] = clr3;
    }

Not really. You declared integers. So for all cases in the loop, the result looks to be zero. May have to think about how to scale that up.

So.. with my current code, I will not be able to generate any waveform?

I tried this as well, but I received an error

for (x = 0; x < H; x++)
    {

        y = H / 2 + sin(x*(2 * pi));
        y = y * 50;
        rgb_data[y][x][0] = 0;
        rgb_data[y][x][1] = 255;
        rgb_data[y][x][2] = 0;
    }

What error? Also, I can't guess if there is something about your c++ compiler and conversions between int and floats. So I'll have to leave it here as, you are using ints and the result of sin() is what? (You tell me because I want you to learn this area as it will be something you deal with for a very long time.)

The main error that I get is that the program does not run and it says access violation writing location

I can't guess which compiler, IDE or such but usually we use a modern one so we know the line that has the error and can examine values.

All that aside, think again what sin() returns. Since you declared all to be integers, maybe you skipped what an integer is?

Let's get back to basics here. Imagine if the output of sin() is as noted at https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/sin-sinf-sinl?view=vs-2019

So the return value of sin(n) is a float from 0.0 to 1.0. If you treat it as an integer then for only one value it might get you a value of 1 but all other values will be zero.

The examples are the link I supplied in this reply work fine. But let's say you need some integer values,

In psuedo-code but again we need floating numbers:

float angle = 0.0;
int maxscale = 100;
for (angle = 0.00; angle < 3.14; angle += 0.01) {
    cout << sin(angle) * maxscale << endl; 
}

And real code. Use this at https://www.tutorialspoint.com/compile_cpp_online.php

Example sin() code with results in 0 to about 100 integers.

#include <iostream>
#include <math.h>

using namespace std;

int main()
{
    cout << "Hello sin()" << endl; 
    float angle = 0.0;
    int maxscale = 100;
    for (angle = 0.00; angle < 3.14; angle += 0.01) {
    cout << int(maxscale * sin(angle)) << endl; 
}
   return 0;
}

Code output:

$g++ -o main *.cpp
$main
Hello sin()
0
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
38
39
40
41
42
43
44
45
46
47
47
48
49
50
51
52
53
53
54
55
56
57
58
58
59
60
61
62
62
63
64
65
65
66
67
68
68
69
70
71
71
72
73
73
74
75
75
76
77
77
78
78
79
80
80
81
81
82
83
83
84
84
85
85
86
86
87
87
88
88
89
89
90
90
90
91
91
92
92
92
93
93
93
94
94
94
95
95
95
96
96
96
96
97
97
97
97
97
98
98
98
98
98
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
99
98
98
98
98
98
98
97
97
97
97
96
96
96
96
95
95
95
94
94
94
93
93
93
92
92
92
91
91
90
90
90
89
89
88
88
87
87
86
86
85
85
84
84
83
83
82
82
81
80
80
79
79
78
77
77
76
75
75
74
73
73
72
71
71
70
69
69
68
67
66
66
65
64
63
63
62
61
60
59
59
58
57
56
55
54
54
53
52
51
50
49
48
48
47
46
45
44
43
42
41
40
40
39
38
37
36
35
34
33
32
31
30
29
28
27
26
25
24
23
22
21
21
20
19
18
17
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0

I think I have found an equation to work out a sine wave, but now I am stuck on the "Design a user interface allowing the user to specify the number of harmonic components to use. The user should also be able to re-run the calculation without exiting the program." part of the program.

Though I am not too sure if my sine wave equation is correct. For the most part it works and prints out the graph I need.

As to not exit etc. menus and such that's basic logic. Example.

Something is true.
Do this while something is true.
Ask the user for input in "this" loop and if they want to exit, set something to false.

Can I have a pseudo code for that? I'm not too sure how to go about it

Thank you. I really appreciate it

Do you know how to do a sum of the waves and plot it as a graph?

This is what I have

{
    int k, n, x, y;
    int sum;

    printf("Enter the number of Wave: ");
    scanf("%d", &k);
    printf("Plotting Graph...\n");
    n = 2 * k - 1;

    int a = 0;
    int b = 255;
    int c = 0;

    do
    {
        for (x = 0; x < W; x++)
        {
            y = H / 2 + H / 3 * 4 / pi * (sin(2 * pi * n * x / T) / n);             
            rgb_data[y][x][0] = a;
            rgb_data[y][x][1] = b;
            rgb_data[y][x][2] = c;

        }
        n--;
        n--;
        a = a + 30;
        b = b + 80;                     //Plots graph in different colours every run
        c = c - 64;
    } while (n >= 1);
    {
        imgwrite();
        for (x = 0; x < W; x++)
        {
            sum = 0;
            for (n = 1; n < k + 1; n++)
            {
                y = (H - 1) / 2 * sin(2 * pi * (2 * n - 1.0) * x / T) / (2 * n - 1.0);          
                sum = sum + y;
            }
            sum = (H / 2) + sum;
            rgb_data[sum][x][0] = a;
            rgb_data[sum][x][1] = b;
            rgb_data[sum][x][2] = c;
        }
    }
}

I need help to plot the square wave of the graph.

In regards to your last post. Your code is uncommented so while you and God knows what you expect, from my view, only God knows and they are not talking to me at the moment.

So I'll have to not look at that code and simply write you might be asking how to add two or more arrays to have a third array then plot that.

only God knows and they are not talking to me at the moment.

Presuming that you are using "they" as a gender-neutral pronoun, then shouldn't that be "they is not talking to me"?
It sounds so wrong, but it's logical.

If, on the other hand you are referring specifically to the Christian 3-in-1 god, then "are" could be correct.

commented: And I didn't account for the no-diety scenario. For that, they are truly on their own. +15

Thank you JC for that. While it's been accepted to use "they" for gender neutral, I failed to resolve for the single or multiple deity point of view.

I have to run now as I see torch lights by the windows. The sound of the tines of the pitchforks was soothing.

I apologise for not commenting on what I wanted your help for my code and to expect too much from your perspective. I've played around with my code and have found the answer that I was looking for.

I am grateful for all the help that you have given me, and I apologise once again for being unprofessional.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.