Skip to content

Instantly share code, notes, and snippets.

@cactorium
Last active October 19, 2016 14:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cactorium/4917a057dc2517640463f4e165d6b826 to your computer and use it in GitHub Desktop.
Save cactorium/4917a057dc2517640463f4e165d6b826 to your computer and use it in GitHub Desktop.
// Same #includes as last time, nothing new here
#include <vector>
#include <iostream>
// C++ has structs just like C!
// This defines a new type of thing, called a Point
// so you can make Points, and they'll all have these exact components
struct Point {
double x, y, z, mass;
};
// This is the function declaration!
// Also known as a prototype
// In C, they're optional
// In C++, they're not
// From this declaration, we see that the return type is a Point,
// the function is called GetCentroid, and it takes in one argument,
// which is kind of complicated so I'll break it down in a bit
// The TLDR is that this basically means that you can call the function
// using a vector of Points as its arguments, and it won't modify your
// vector of Points at all, and it'll also avoid making a copy of them,
// which is what C/C++ does to most arguments in functions
//
// The core of it is a std::vector<Point>, a vector of Points, like we
// had in the last class, but that's surrounded by two new things,
// const and &
// const is short for constant
// When a variable has this attribute, it means you aren't allowed to modify
// the variable, only reading it, and using methods and whatever else that
// avoid modifying it
// Put it when you can because it helps programmers figure out what your
// function does
//
// The & probably looks kind of familiar if you've programmed in C before,
// but here it's pretty different
// In C, it means "the address of", for getting a pointer to a variable
// Here's it's used like the * in a pointer declaration; it means reference
// So here we have a reference to a constant vector of Points
// A reference basically the same thing as a pointer, except you get to treat
// the variable like a normal variable; you don't need to bother with the dereferencing
// stuff
// You also can't do any pointer arithmetic, and the pointer's never null,
// so it's a little safer
// However, unlike pointers, references are basically only used in function declarations
// Here they let you avoid copying objects, and also allow you to modify variables
// the same way pointers do in C, except safer
// They let you avoid copying objects because you can just pass a reference to it
// instead of having to make a copy of it like you normally would if you tried
// to pass a variable in a function
//
// By the way, C++ has pointers like C, but generally unlike C, you should avoid
// using them like the plague, because there's better, safer, ways in C++ that
// we'll get to eventually
//
// Aaand just like last time, half the lesson's based on a single line of code
// I should probably work on not doing that..
Point GetCentroid(const std::vector<Point>& points);
// The program starts in main() as most of the time
int main() {
// Let's make a program that calculates the centroid, or center of mass,
// of an unknown number of points
// First we ask the user for the number of points they want to input
// We initialize an integer variable to store the number of points
int numPoints = 0;
// Like before std::cout << stuff
// prints stuff out to the command line
std::cout << "Enter the number of masses: ";
// Similarly std::cin >> stuff
// takes data from the user input and sticks it in that variable
std::cin >> numPoints;
// We need a place to store the points, and a vector's a good a choice as any
auto points = std::vector<Point>();
// We know the user wants to enter numPoints points, so we loop that many times
for (int i = 0; i < numPoints; ++i) {
// We make a temporary variable to store the user's input
Point tmp;
// And then populate it using the data from std::cin
std::cout << "Enter a mass: (x y z mass)\n";
std::cin >> tmp.x >> tmp.y >> tmp.z >> tmp.mass;
// And add it to the vector; like before, this means "add tmp to points"
//
// I don't think I covered this well before, but this is a method call
// C++ is object oriented, so objects can have methods related to them,
// and methods are basically functions that are very closely related to the
// objects they're attached to
// So this call is something like
// "call point's method push_back using tmp as the argument"
// Methods can be defined for certain types in C++, we'll probably discuss
// that soon
//
// Anyways, at the end of this loop points will store all the data that the
// user entered in what's effectively a big array
points.push_back(tmp);
}
// Here we store the value we get from GetCentroid in centroid and print
// out the results
auto centroid = GetCentroid(points);
std::cout << "Total mass: " << centroid.mass << "\n";
std::cout << "The center of mass is " << centroid.x <<
", " << centroid.y <<
", " << centroid.z << "\n";
return 0;
}
// We declared the function already, above the main() function, but now
// we need to define it so we can actually use it
Point GetCentroid(const std::vector<Point>& points) {
double totalMass = 0.0, totalX = 0.0, totalY = 0.0, totalZ = 0.0;
// Following the formula in Wikipedia, the position of the centroid
// is the weighted average of the positions of all the points, or put more
// simply, the sum of coordinates of each point, multiplied by its individual mass,
// with the sum divided by the total mass of all the points
//
// It turns out we can calculate both the total mass and the sum of point coordinates
// in a single pass over the vector of points, so we'll do that
for (Point p: points) {
totalMass += p.mass;
totalX += p.mass*p.x;
totalY += p.mass*p.y;
totalZ += p.mass*p.z;
}
// Here we see an example of another new bit of C++ syntax;
// Point{.....} is an expression that is defines a new point
// This works for any struct, and the fields, the variables inside a struct,
// will be initialized in the same order they appear in that expression
// So Point{1.0, 2.0, 3.0, 4.0} will have
// an x value of 1.0,
// a y value of 2.0,
// a z value of 3.0,
// and a mass value of 4.0
//
// Here we pass that into the return statement so that the function
// returns the centroid coordinates and total mass
return Point{totalX/totalMass, totalY/totalMass, totalZ/totalMass, totalMass};
}
// And we're done!
// The homework for this week is to come up with a program that does something
// else with moments of inertia or something, preferably using vectors in the
// process
// Good luck!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment