how to write this program for C++ - c++

I need help with this question: A piece of wire is to be bent in the form of a rectangle to put around a picture frame. The length of the picture frame is 1.5 times the width. Write a program that prompts the user to input the length of the wire and the outputs the length and the width of the picture frame. I'm not sure if I should code something that has got to do with the perimeter.
I've tried to start it
#include <iostream>
using namespace std;
int main() {
double length;
double width;
cout << "Input the length of the wire:";
cin >> length;
cout << endl;
return 0;
}

Hint:
Well you know that the length of the wire. So let's call that L.
Width will be fW and length of frame will be fL.
Then you have:
2*fW + 2*fL = L.
fL = 1.5*fW
2*fW + 2*(1.5*fW) = L
L = 5*fW
fW = L/5.
So basically you know that the width of the frame will be length of wire divided by 5. And length will be 1.5 times that.

Related

How can one write a multi-dimensional vector of image data to an output file?

Question:
Is there a good way to write a 3D float vector of size (9000,9000,4) to an output file in C++?
My C++ program generates a 9000x9000 image matrix with 4 color values (R, G, B, A) for each pixel. I need to save this data as an output file to be read into a numpy.array() (or similar) using python at a later time. Each color value is saved as a float (can be larger than 1.0) which will be normalized in the python portion of the code.
Currently, I am writing the (9000,9000,4) sized vector into a CSV file with 81 million lines and 4 columns. This is slow for reading and writing and it creates large files (~650MB).
NOTE: I run the program multiple times (up to 20) for each trial, so read/write times and file sizes add up.
Current C++ Code:
This is the snippet that initializes and writes the 3D vector.
// initializes the vector with data from 'makematrix' class instance
vector<vector<vector<float>>> colorMat = makematrix->getMatrix();
outfile.open("../output/11_14MidRed9k8.csv",std::ios::out);
if (outfile.is_open()) {
outfile << "r,g,b,a\n"; // writes column labels
for (unsigned int l=0; l<colorMat.size(); l++) { // 0 to 8999
for (unsigned int m=0; m<colorMat[0].size(); m++) { // 0 to 8999
outfile << colorMat[l][m][0] << ',' << colorMat[l][m][1] << ','
<< colorMat[l][m][2] << ',' << colorMat[l][m][3] << '\n';
}
}
}
outfile.close();
Summary:
I am willing to change the output file type, the data structures I used, or anything else that would make this more efficient. Any and all suggestions are welcome!
Use the old C file functions and binary format
auto startT = chrono::high_resolution_clock::now();
ofstream outfile;
FILE* f = fopen("example.bin", "wb");
if (f) {
const int imgWidth = 9000;
const int imgHeight = 9000;
fwrite(&imgWidth, sizeof(imgWidth), 1, f);
fwrite(&imgHeight, sizeof(imgHeight), 1, f);
for (unsigned int i=0; i<colorMat.size(); ++i)
{
fwrite(&colorMat[i], sizeof(struct Pixel), 1, f);
}
}
auto endT = chrono::high_resolution_clock::now();
cout << "Time taken : " << chrono::duration_cast<chrono::seconds>(endT-startT).count() << endl;
fclose(f);
The format is the following :
[ImageWidth][ImageHeight][RGBA][RGBA[RGBA]... for all ImageWidth * ImageHeight pixels.
Your sample ran in 119s in my machine. This code ran in 2s.
But please note that the file will be huge anyway : you are writing the equivalent of two 8K files without any kind of compression.
Besides that, some tips on your code :
Don't use a vector of floats to represent your pixels. They won't have more components than RGBA. Instead create a simple struct with four floats.
You don't need to look through width and height separately. Internally all lines are put sequentially one after the other. It is easier to create a one dimension array of width * height size.

C++ Assignment for Intro Engineering

This is the problem my professor wants me to solve with a C++ program...
To design a square timber column in a structure, three formulas must
be satisfied:
column pcture-1.jpg
Buckling load: The maximum load the column can hold for buckling which needs to be greater than the expected load on the column.
Maximum load = (.3 x E x Area) / (Length / Width)2
Compressive stress: The maximum load the column can hold for compression which needs to be greater than the expected load on the
column.
Maximum load = Area x Maximum compressive strength
Slenderness limit: Ratio of Length to Width of the column must be less than or equal to 50
(Length / Width)<= 50
where: E = the modulus of elasticity = 1,700,000 lb/in2
Area = width x width = the cross sectional area in square inches
Maximum compressive strength = 445 lb/in2 for a Douglas Fir tree.
Write a program that uses these three formulas to give an initial
design to a structural engineer. Assume the columns to be used are
square in cross-section and are available in intervals of 2 inches
(i.e. 2 by 2, 4 by 4, 6 by 6 and so on). Have the output look like
the following:
Please enter the expected load on the column in pounds--> 9000
Please enter the length of the column in inches--> 120
... .Testing a beam with Area of 2.0 by 2.0 inches – Failed the tests
... .Testing a beam with Area of 4.0 by 4.0 inches – Failed the tests
... .Testing a beam with Area of 6.0 by 6.0 inches – Passed the 3 required tests
For a load of 9000.0 pounds and a length of 120.0 inches, recommended
square beam has sides of 6.0 inches The timber cost will be $ 216
You must write a function for each of the three tests using call by
value. Your main program will call these three functions in order to
solve the problem. Test your program for the above input and for the
case of 18000 lb load and column length 72 inches. If the price of
the timber is 0.05 $/in3 report the difference between the cost of
the timbers.
This is the program I wrote, but it forms an endless loop; I am not sure how to fix it, and solve the problem my professor wants me to.
#include <iostream>
#include <fstream> // outfile
#include <cmath>
#define E 1700000 // lb/in^3 (E is modulus of elasticity)
#define MCS 445 // lb/in^3 (MCS is maximum compressive strength)
using namespace std;
bool buckling_load();
bool compressive_stress();
bool slenderness_limit();
//1.0 declare variables
float expected_load;
float column_length;
bool tests_passed = false;
float column_width = 2;
int main() {
ofstream outfile;
outfile.open("outfile.txt");
//2.0 get user input
cout << "Please enter the expected load on the column (lbs), and the
column length (in) ->" << endl;
cin >> expected_load >> column_length;
//3.0 test the different widths
while (!tests_passed) {
if (buckling_load() && compressive_stress() && slenderness_limit()){
tests_passed = true;
cout << column_width << " by "<< column_width << " Passed the three required tests";
}
else {
cout << column_width << " by "<< column_width << " Failed the three required tests";
column_width +=2;
}
}
}
//4.0 define functions
bool buckling_load(){
if (expected_load < ((0.3 * E * pow(column_width, 2)) / pow(column_length / column_width, 2))){
return true;
}
else{
return false;
}
}
bool compressive_stress(){
if (expected_load < ((pow(column_width,2)) * MCS)){
return true;
}
else{
return false;
}
}
bool slenderness_limit(){
if(50 <= (column_length/column_width)){
return true;
}
else {
return false;
}
}
This condition
Slenderness limit: Ratio of Length to Width of the column must be less
than or equal to 50
does not correspond to your source:
bool slenderness_limit(){
if(50 <= (column_length/column_width)){
return true;
}
else {
return false;
}
}
The condition should be reversed:
if(50 >= (column_length/column_width))

Reading BMP file into an array

I am writing a longer program and I found myself needing to read a .bmp file into an array in a specific way so that the rest of the program can use it without extensive rewrites. I failed to find older answers that would resolve my problem, and I am pretty much at the beginner stages.
The image I am trying to read is used to create a text font, so I want to read it character by character into an array, where the pixels belonging to one character are added in order to a 2d bool (true if pixel is not black) array [character_id] [pixel_n]. The dimensions of characters are predetermined and known, and the file is cropped so that they all appear in a single row with no unaccounted margins.
This is the specific file I am trying to read, though here it might not show up as .bmp
As an example, shown here, I want to read the pixels in the order of the yellow line, then jump to another character. For clarity each character is 5px wide and 11px high, with 1px of margin on both sides horizontally.
Based on what I was able to find, I have written a function to do it, but I fail to make it work as intended, as far as I can tell even the pixel values are not being read correctly:
void readBMP(char* filename)
{
int i;
FILE* f = fopen(filename, "rb");
unsigned char info[54];
// read the 54-byte header
fread(info, sizeof(unsigned char), 54, f);
// extract image height and width from header
int width = *(int*)&info[18];
int height = *(int*)&info[22];
// number of pixels in total
int size = 3 * width * height;
unsigned char* data = new unsigned char[size];
// number of characters to read
int counter1 = size / ((font_width + 2) * font_height) / 3 ;
// read the rest of the data at once
fread(data, sizeof(unsigned char), size, f);
fclose(f);
//loop that goes from character to character
for(int i = 0; i < counter1; i++)
{
int tmp = 0;
//loop that reads one character into font_ref array
for(int j = 0; j < font_height; j++)
{
//loop for each row of a character
for(int k = 0; k < font_width; k++)
{
int w = static_cast<int>(data[3*(j*(font_width+2)*(counter1) + i*(font_width + 2) + 1 + k + j*font_width + j)-1]);
if( w != 0 )
font_ref [i][(tmp)] = 1;
else
font_ref [i][(tmp)] = 0;
tmp++;
}
}
}
}
(bool font_ref [150][font_width*font_height]; is the array where the font is being loaded and stored)
this code reads something, but the result is a seemingly random mess and I am unable to resolve that. Here is an example of lowercase alphabet printed using another function in the program, where white pixels represent true bools. I am aware that some libraries exist to work with graphical files, however in this program I wanted to possibly avoid that to learn more lower-level things, and the goal is rather limited and specific.
Thank you in advance for any help with the issue.
The main errors are in the offset computation for a pixel in the bitmap data:
int w = static_cast<int>(data[3*(j*(font_width+2)*(counter1) + i*(font_width + 2) + 1 + k + j*font_width + j)-1]);
j*(font_width+2)*(counter1) - This doesn't take into account that
although you say the file is cropped, there is extra black space to the right of the last character cell, so the true width must be used;
(as drescherjm and user3386109 mentioned) padding bytes are appended to the rows so that their length is a multiple of four bytes.
+ j*font_width + j)-1 - This part makes no sense - perhaps you tried to compensate the above errors.
This would be correct:
int w = data[j*(3*width+3&~3)+3*(i*(font_width+2)+1+k)];

C++ - Trying to read a .PPM image, unexpected output

I'm developing a uni project for reading the image data of P6-type, 255-depth .ppm images. The problem I encounter is that when I try to print the average values of each color (R,G,B) for an Image, the output I get is wrong (the proffessor has given us an output file which says what float values to expect for each given image).
Now, I'm at a loss here. Through many checks, I have concluded that the function reads the whole data from the image, without leaving out pixels or whatever, converts them correctly from 0-255 to 0.f - 1.f values (by dividing with 255.0), adds every red, every green and every blue value to three seperate counters and then divides them by the Width*Height of the given image to get the desired average brightness of each colour. I will provide part of the function that does this process for calculating the average red for a 960*642 Image (sorry for the hardcoded stuff, it's just there for debugging purposes).
The output I get for this is 0.58... when it should be 0.539068. seekg() is called with 14 as an argument because position 14 is the last space after the header and before the data. Could you provide any insight to why this isn't working as expected? One thing I found through the checks is the sum I get after adding all the red float values, is not a float but an int. Possible loss of data? I'm grasping at straws here.
Here is the code:
std::ifstream infile;
infile.open("Image02.ppm", std::ios::in | std::ios::binary);
const unsigned char* buffer;
float * data_ptr;
infile.seekg(0, std::ios::end);
int length = infile.tellg(); //calculating length of data
buffer = new unsigned char[length];
ptr = new unsigned char[length];
data_ptr = new float[length];
infile.seekg(14, std::ios::beg); //restoring pointer to the start of data stream
infile.read((char*)buffer, length); //reading the image
for (int i = 0; i < length; i++){ //casting the char data to floats to get the 0-255 values
data_ptr[i] = ((float)buffer[i]);
data_ptr[i] = data_ptr[i] / 255.f; // converting to 0.0 - 1.0
}
int j = 0;
float a = 0.f;
while (j < length){ //calculating sum of red pixel values
a = a + data_ptr[j];
j = j + 3;
}
std::cout << a / (960*642); //calculating average
FYI, PPM image files that are P6 have their image data stored from left to right, with the first line being line 0 and the last line of the image being the last. They are structured like this R G B R G B R G B so on, where the first RGB correspond to the first pixel and so forth.
Thanks in advance!
You need pixels only for average calculation.
But in your source code, additional 14 garbage values are being used.

Writing to .BMP - distorted image

I'd like to write a normal map to a .bmp file, so I've implemented a simple .bmp writer first:
void BITMAPLOADER::writeHeader(std::ofstream& out, int width, int height)
{
BITMAPFILEHEADER tWBFH;
tWBFH.bfType = 0x4d42;
tWBFH.bfSize = 14 + 40 + (width*height*3);
tWBFH.bfReserved1 = 0;
tWBFH.bfReserved2 = 0;
tWBFH.bfOffBits = 14 + 40;
BITMAPINFOHEADER tW2BH;
memset(&tW2BH,0,40);
tW2BH.biSize = 40;
tW2BH.biWidth = width;
tW2BH.biHeight = height;
tW2BH.biPlanes = 1;
tW2BH.biBitCount = 24;
tW2BH.biCompression = 0;
out.write((char*)(&tWBFH),14);
out.write((char*)(&tW2BH),40);
}
bool TERRAINLOADER::makeNormalmap(unsigned int width, unsigned int height)
{
std::ofstream file;
file.open("terrainnormal.bmp");
if(!file)
{
file.close();
return false;
}
bitmaploader.writeHeader(file,width,height);
for(int y = 0; y < height; y++)
{
for(int x = 0; x < width; x++)
{
file << static_cast<unsigned char>(255*x/height); //(unsigned char)((getHeight(float(x)/float(width),float(y)/float(height))));
file << static_cast<unsigned char>(0); //(unsigned char)((getHeight(float(x)/float(width),float(y)/float(height))));
file << static_cast<unsigned char>(0); //(unsigned char)((getHeight(float(x)/float(width),float(y)/float(height))));
};
};
file.close();
return true;
};
The writeHeader(...) function is from SO, from a solved,working post. (I've forgot the name of it)
The getHeight(...) is using bicubic interpolation, so I can write it to big resolution images, and it stays smooth. It will be also used for collision detection and now is used as a LOD factor for my clipmaps.
Now the problem is that this outputs a distorted image. The pictures will tell everything I think:
The expected/distorted result(s):
for the heightmap: I have the function that describes a mesh: getHeight(x,z). It gives back the correct results because I've tested it with shaders (by sending heights as vertex attribs) too. The image downloaded from internet:
And with the y(x,z) function values written to a .BMP: (the commented out part of the code):
With a simple function: file << static_cast<unsigned char>(255*(float)x/height)
which should be a simple blend from black to white to the right.
I used an image size of 256 x 256, because I've read it should be multiple of 4. I CAN use libraries, but I'd like to solve this problem without one. So, what caused this distortion?
EDIT:
On the last image some lines are also colored, but they shouldn't be. This post is similar, but my heightmap is not distorted linearly as in this post: Image Distortion with Lock Bits
EDIT:
Another strange issue is when I don't make all colors the same, it get's distorted in colors too. For example set only the RED to the heights, and leave G and B 0, it became not only RED, but a noisy colored heightmap.
EDIT /comments/
If I understood them right, there's the size of the header, then comes my pixel data. Now before the pixel data there must be 4 * n bytes. So that padding mean after the header I put some more data that fills the place.
For example assuming (I will look up hot to get it exactly) my header is 55 bytes, then I should add 1 more byte to it because 55+1 = 56 and 4|56.
So
file << static_cast<unsigned char>('a');
for(int y = 1; y <= width; y++)
{
for(int x = 1; x <= height; x++)
{
file << static_cast<unsigned char>(x);
file << static_cast<unsigned char>(x);
file << static_cast<unsigned char>(x);
};
};
should be correct.
But I realized the real issue (as Jigsore commented). When I cast from int to char, it seems like a 1 digit number becomes 1 byte, 2 digits number 2, and 3 digits 3 bytes. Clamping the height to 3 digits works well, but the image is a bit whitey, because 'darkest' color becomes (100,100,100) instead of (0,0,0). Also, this is the cause of the non-regular distortion, because it depends on how many 'hills' or 'mountains' are there in one row. How can I solve this, and I hope the last problem? I don't want to compress the image to 100-256 range.;)
Open your file in binary mode.
Under Windows, if you open a file in the default text mode, it will write an extra 0x0d (Return) character after every 0x0a (Linefeed) that gets written out. The first time this happens it will change the colors of the following pixels, as the RGB order gets out of alignment. After it happens 3 times you'll be off by a full pixel.