• Need help devising a formula for calculating length of a spool of wire
    25 replies, posted
The user inputs the weight and wire thickness of the spool. Various densities of materials are defined in the header file. I should be able to calculate the volume and length of the spool based on this, but I simply can't devise a formula for it. Should be something along the lines of [code] volume = (PI * (wireThick / 2) * (wireThick / 2) * spoolLength) spoolLength = what? [/code]
[code]spoolLength = (mass / (density * PI * (wireThick / 2) * (wireThick / 2)))[/code]
[QUOTE=NullPoint;18909190][code]spoolLength = (mass / (density * PI * (wireThink / 2) * (wireThink / 2)))[/code][/QUOTE] Almost: [code]spoolLength = (mass / (density * PI * wireThick * wireThick / 4 ))[/code] A better formula is: A = (pi * d^2)/4 Since you have a diameter, not a radius. And you spelled 'Thick' wrong :p
[QUOTE=Mattz333;18909394]Almost: [code]spoolLength = (mass / (density * PI * wireThick * wireThick / 4 ))[/code] A better formula is: A = (pi * d^2)/4 Since you have a diameter, not a radius. And you spelled 'Thick' wrong :p[/QUOTE] They are exactly the same. [editline]11:58AM[/editline] [code](i^2)/4 == (i/2)^2 [/code]
Thanks. main.cpp [cpp] #include "ring.h" #include "spool.h" #include <string> #include <iostream> int main() { spool userSpool; ring userRing; std::cout << "Input wire thickness:\t"; std::cin >> userSpool.wireThick; std::cout << "\n" << "Input weight in grams:\t"; std::cin >> userSpool.weight; std::cout << "\n" << "Input material:\t"; std::cin >> userSpool.material; std::cout << "\n" << "Length of spool is:\t" << userSpool.getLength() << " centimeters.\n"; std::cout << "\n" << "Input inner diameter:\t"; std::cin >> userRing.innerDiam; std::cout << "\n" << "Input wire thickness:\t"; std::cin >> userRing.wireThick; std::cout << "\n" << "Input material:\t"; std::cin >> userRing.material; std::cout << "\n" << "The ring is made of " << userRing.material << " and has an aspect ratio of " << userRing.getAspectRatio() << " and weighs " << userRing.getWeight() << " g" << "\n" << "the wire used for the ring is " << userRing.getLength() << " mm long.\n"; std::cin.ignore(); std::cin.get(); return 0; } [/cpp] ring.h [cpp] #define PI 3.14159265358979323846264338327950 #define GOLD 19.300 //g/cm^2 #define SILV 10.500 #define COPP 8.960 #define STEE 7.800 #define ALUM 2.700 #pragma once #include <iostream> #include <string> class ring { public: double innerDiam; double wireThick; std::string material; double getAspectRatio(); double getWeight(); double getLength(); }; double ring::getAspectRatio() { return innerDiam / wireThick; } double ring::getWeight() { double volume; double circumference; double weight; double density; circumference = innerDiam + (wireThick / 2) * PI; volume = (PI * (wireThick / 2) * (wireThick / 2) * circumference) / 100; //Check material if (material == "Gold") { density = GOLD; } else if (material == "Silver") { density = SILV; } else if (material == "Copper") { density = COPP; } else if (material == "Steel") { density = STEE; } else if (material == "Aluminium") { density = ALUM; } weight = density * volume; return weight; } double ring::getLength() { double circumference; circumference = innerDiam + (wireThick / 2) * PI; return circumference; } [/cpp] spool.h [cpp] #define PI 3.14159265358979323846264338327950 #define GOLD 19.300 //g/cm^2 #define SILV 10.500 #define COPP 8.960 #define STEE 7.800 #define ALUM 2.700 #pragma once #include <iostream> #include <string> class spool { public: double wireThick; double weight; std::string material; double getLength(); }; double spool::getLength() { double density; if (material == "Gold") { density = GOLD; } else if (material == "Silver") { density = SILV; } else if (material == "Copper") { density = COPP; } else if (material == "Steel") { density = STEE; } else if (material == "Aluminium") { density = ALUM; } double length; length = (weight / (density * PI * (wireThick / 2) * (wireThick / 2))); return length; } [/cpp] Any suggestions for improvement? Edit: Updated with ThePuska's suggestion.
You've got a bunch of consecutive ifs out of which only one [i]needs to be[/i] executed - therefore you should write [code]if (material == "Gold) { ... } else if (material == "Silver") { ... } etc.[/code]
[QUOTE=ThePuska;18909962]You've got a bunch of consecutive ifs out of which only one gets executed - therefore you should write [code]if (material == "Gold) { ... } else if (material == "Silver") { ... } etc.[/code][/QUOTE] They will all be executed, but only one needs to be. That's why he needs the elseifs
Yep. Flush the streams with std::endl for newline + flush or std::flush for just a flush when you want the output to appear. It might already do that, but I wouldn't take chances. Write a small convenience-function to get double- and string-input, which checks for errors and if so, tells the user that and clears the error-flags so (s)he can try again. The spool- and wire-class look quite similar. Maybe you could use some inheritance here? The chain of if .. if .. if can be faster with if .. else if .. else if. You could also take a look at std::maps, but I don't think there's a pretty way to initialize them without boost. You can just use the constructor though. And since it's the same for all instances, you should make this member static (if you use a std::map). You should notify the user, if a certain material he entered does not exist in the programs databank and ask the user kindly for the density of it or if he maybe just mistyped. The std::map would play in nicely here. But the function-definitions in an implementation-file, rather than the header. Short functions should stay in the header though, so they can be inlined. Use real include-gaurds, #pragma once is MSVS only I think and certainly not standard. Put the constants in a shared header and use const static double/float instead of #define. You can do return [formula here] directly, and don't have to create a temporary variable. You could think about getting the variables inside the classes themselves. It would look nicer IMO and is easier extendable: [cpp]void spool::getVariables(std::istream &input, std::ostream &output) { output << "Input wire thinkness:\t" << std::flush; //... }[/cpp]
Is it possible to do something like this? spool.h [cpp] double spool::getNumRings() { return spool::getLength() / ring::getLength(); //is from ring.h } [/cpp]
If ring is a baseclass of spool or getLength a static member of the class ring, yes.
[QUOTE=ZeekyHBomb;18910129]Yep. Flush the streams with std::endl for newline + flush or std::flush for just a flush when you want the output to appear. It might already do that, but I wouldn't take chances. Write a small convenience-function to get double- and string-input, which checks for errors and if so, tells the user that and clears the error-flags so (s)he can try again. The spool- and wire-class look quite similar. Maybe you could use some inheritance here? The chain of if .. if .. if can be faster with if .. else if .. else if. You could also take a look at std::maps, but I don't think there's a pretty way to initialize them without boost. You can just use the constructor though. And since it's the same for all instances, you should make this member static (if you use a std::map). You should notify the user, if a certain material he entered does not exist in the programs databank and ask the user kindly for the density of it or if he maybe just mistyped. The std::map would play in nicely here. But the function-definitions in an implementation-file, rather than the header. Short functions should stay in the header though, so they can be inlined. Use real include-gaurds, #pragma once is MSVS only I think and certainly not standard. Put the constants in a shared header and use const static double/float instead of #define. You can do return [formula here] directly, and don't have to create a temporary variable. You could think about getting the variables inside the classes themselves. It would look nicer IMO and is easier extendable: [cpp]void spool::getVariables(std::istream &input, std::ostream &output) { output << "Input wire thinkness:\t" << std::flush; //... }[/cpp][/QUOTE] I'm not really that familiar with classes (yet). I started to "understand" how they work the day before yesterday.
[QUOTE=NullPoint;18909999]They will all be executed, but only one needs to be. That's why he needs the elseifs[/QUOTE] What's wrong with a switch statement?
[QUOTE=compwhiziitothemax;18912952]What's wrong with a switch statement?[/QUOTE] Nothing, I would use a switch statement for this.
C++ supports switch only for built-in types. std::string is not a built-in type. Correction: Only of integral types: [code]1>eh.cpp(41): error C2450: switch expression of type 'int *' is illegal 1> Integral expression required[/code]
[QUOTE=ZeekyHBomb;18913644]C++ supports switch only for built-in types. std::string is not a built-in type.[/QUOTE] Ah, I wasn't aware of that.
Yeah I discovered that yesterday when I tried. Would've been useful though.
So why not use an Enum instead of a string for the material types? If you used an Enum, you could switch it
Because the user needs to input it. I already suggested a map<string, double> for it.
[QUOTE=ZeekyHBomb;18924006]a map<string, double> for it.[/QUOTE] do it op
OP seems to be in an early phase of learning C++; I'd say that (s)he doesn't yet know how to handle a std::map.
[QUOTE=Armandur;18909101]The user inputs the weight and wire thickness of the spool. Various densities of materials are defined in the header file. I should be able to calculate the volume and length of the spool based on this, but I simply can't devise a formula for it. Should be something along the lines of [code] volume = (PI * (wireThick / 2) * (wireThick / 2) * spoolLength) spoolLength = what? [/code][/QUOTE] Use a ruler.
The wire can be modeled as a cylinder. You have the mass, density and diameter of the cylinder. Solve for length. This is the programming forum. Not the basic algebra forum.
Doesn't a spool have a hole down the middle?
get the mass of the spool hole and subtract it from the mass of the main cylinder
[QUOTE=turby;18934594]get the mass of the spool hole and subtract it from the mass of the main cylinder[/QUOTE] Can a hole have mass? For those who are rating me dumb, I was being sarcastic. A hole is a lack of matter, thus will not have any mass.
A hole in a spool of wire is air, which has mass. But anyway, what I meant was to get a mass of the spool in the area that will be chopped out and subtract it.
Sorry, you need to Log In to post a reply to this thread.