euclidean distance

Hi

Can someone help me out quick.

Here is the contents of my h file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

class Location {

private:
    int x;
    int y;

public:
    Location(int, int);
    int getX();
    int getY();
    float computeDistance(const Location &loc);
    string toString();
};


How would I set up the computeDistance member function ? I've done all the other functions, just stuck on that one.

Thanks
Last edited on
1
2
3
4
5
6
7
8
#include <cmath>

// ...
{
    float dx = loc.x - x;
    float dy = loc.y - y;
    return std::sqrt(dx * dx + dy * dy);
}
Last edited on
How do I incorporate the const Location and the &loc. I understand the formula just not how to use with those variables ?
Last edited on
Lol fine, I'll do it for you...
1
2
3
4
5
6
float Location::computeDistance(const Location &loc)
{
    float dx = loc.x - x;
    float dy = loc.y - y;
    return std::sqrt(dx * dx + dy * dy);
}
For future reference, const Location &loc is a reference to a constant location to which you give the name loc.
How do I incorporate the const Location and the &loc.

Interesting question.

If you wrote the "h file" yourself, would you then know why you wrote
float computeDistance(const Location &loc); in it?
If you did write and do know, then why the question?

Perhaps you were given the h file and simply asked to add the function implementations?
If yes, what on that member function was different from the others?

Have you used by reference function arguments before?
Have you used const before?

The point is, if you had trouble with one, how do you know that you got the others right?


The h file has inconsistent style, and lacks const correctness. How about:
1
2
3
4
5
6
7
8
9
10
11
class Location {
private:
    int x;
    int y;
public:
    Location(int, int);
    int getX() const;
    int getY() const;
    float computeDistance(const Location &) const;
    string toString() const;
};

Only the constructor seems to modify the object's state. Const member functions improve safety and usability.

Names are optional on function declarations. If constructor does not tell the names of its arguments, why should the computeDistance do so?
However, now the user needs some additional documentation in order to know what data the functions expect. Hence:
1
2
3
4
5
6
7
8
9
10
11
class Location {
private:
    int x;
    int y;
public:
    Location(int y, int x); // Did I name these right?
    int getX() const;
    int getY() const;
    float computeDistance(const Location & loc) const;
    string toString() const;
};
The h file was given to me and that's why I'm confused with the const Location &loc part.

This does not work as I can't get my main.cpp call to that function to work as I can't figure out what the const location &loc means, hence my asking:
1
2
3
4
5
6
float Location::computeDistance(const Location &loc)
{
    float dx = loc.x - x;
    float dy = loc.y - y;
    return std::sqrt(dx * dx + dy * dy);
}


here is my main.cpp as of now:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include "Location.h"
#include "MovieFile.h"

using namespace std;

int main()
{
    Location PTA(10, 89);
    PTA.getX();
    PTA.getY();
    PTA.computeDistance();//not sure what to pass
    PTA.toString();


    

    return 0;
}



Back to basics then. See http://www.cplusplus.com/doc/tutorial/functions/
There are sections "Arguments passed by value and by reference" and "Efficiency considerations and const references".
(Start of that page has also functions that return a value.)


You have object "PTA". PTA is a Location.

Doesn't "distance" mean "distance between two locations"? Two.

PTA is one location. What is the other location?
You understand that to have a distance, there must be two points for there to be a distance between, yes?

You understand that, in the context of your code, such a point is represented by a Location object, yes?

So, for the Location::computeDistance() method, you're calculating the distance from the Location object you're calling the method on, and a second Location object. That second Location object is passed into the computeDistance() method.

As Optimistic Peach has already explained, const Location &loc means that you're passing it in as a constant reference.

Since you decided not to bother answering the questions that keskiverto took the time and effort to ask you, can we assume you already know what that means?
Last edited on
keskiverto the .h file was made using this info:

Member Functions:
• Location(int, int): constructor that receives the x and y coordinates
• int getX(): returns the x coordinate
• int getY(): returns the y coordinate
• float computeDistance(const Location& loc): computes the Euclidean distance
between the current and input location objects
• string toString(): returns the location coordinates in the following string
format: (x,y) (no spaces in between or around the string)


This is the main my lecturer uploaded today:

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
#include <iostream>
#include "Location.h"
#include "MovieFile.h"

using namespace std;

int main()
{
    //--------------------------------------------
	//      Example code: Location class
    //--------------------------------------------
    Location* loc1 = new Location(30,10);
    Location* loc2 = new Location(20,20);
    
    cout << loc1->computeDistance(*loc2) << endl;            //output: 14.1421
    cout << loc2->toString() << endl;                                    //output: (20,20)
    
    delete loc1;
    delete loc2;
    loc1 = nullptr;
    loc2 = nullptr;
    
/*
    //--------------------------------------------
	//      Example code: MovieFile class
    //--------------------------------------------
    MovieFile* movie1 = new MovieFile("Black Panther", 120, 350);
    cout << movie1->getFileSize() << endl;      //output: 350
    movie1->setFileSize(50) ;    
    cout << movie1->getFileSize() << endl;       //output: 50
   
    delete movie1;
    movie1 = nullptr;

 */
//ignore the commented out section
	return 0;
}


Here is my .cpp file:

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
#include <iostream>
#include <cmath>
#include "Location.h"
using namespace std;


Location::Location(int, int)
{
    ;
}

int Location::getX()
{
    cout<<"X coordinate is "<<x<<endl;
    return x;
}

int Location::getY()
{
    cout<<"Y coordinate is "<<y<<endl;
    return y;
}

float Location::computeDistance(const Location &loc)
{

    float loc1 = loc.x - x;
    float loc2 = loc.y - y;
    return sqrt(loc1 * loc1 + loc2 * loc2);
}


string Location::toString()
{
    cout<<"("<<x<<","<<y<<")"<<endl;
}
1. Do you understand what a constructor is and what it is supposed to do? A constructor's job is to initialize members of the object.

1
2
3
4
Location::Location(int, int)
{
    ;
}


In this case, you are passing 2 integer values into the constructor. These values would normally be assumed to be the x and y coordinates for the point representing the location. Not surprisingly, the Location class has members x and y which would normally be initialized in this constructor. However, you did not write any code to initialize these members. A better way to write this function would be:

1
2
3
4
5
Location::Location(int newx, int newy)
{
    x = newx;
    y = newy;
}


Note: There is a better way to write this using a constructor initializer list, but let's not confuse things right now.

2.

1
2
3
4
5
6
7
float Location::computeDistance(const Location &loc)
{

    float loc1 = loc.x - x;
    float loc2 = loc.y - y;
    return sqrt(loc1 * loc1 + loc2 * loc2);
}


Technically this is correct. However, the names of your variables are terrible. The difference loc.x - x is the difference between x coordinates, not a location. The name loc1 implies that this is a location, so the variable name hides what the variable actually is.

@Ganado suggested dx in his first post--that's a good name. Another good names would be deltax or xdiff. Learn to use variable names that are clear, concise and correct.
Last edited on
I originally had my constructor in a similar format to yours @doug4 but my output was not the same as that of the comments within the main.cpp above, thus I removed them. I removed them to see what would happen.

It did look like this, Is this correct ?
1
2
3
4
5
Location::Location(int, int)
{
    x = 10;
    y = 89;
}




1
2
 Location* loc1 = new Location(30,10);
 Location* loc2 = new Location(20,20);

Based on the main.cpp section above, am I correct in saying that loc1 and loc2 are actually names of objects created from the Location object, instantiations of Location ?

I'll also go and change the computeDistance function's variable names as well. If I can check that these member functions all work I can move onto the next part of the assignment.

I'm a serious c++ noob so I'm definitely making stupid mistakes.
Last edited on
1
2
3
4
5
Location::Location(int, int)
{
    x = 10;
    y = 89;
}

Think about it this way: What is the point of having to pass in two ints, if you never use those ints? The two ints you passed in having meaning, right? But you don't use them. Start by giving the two ints actual names so that you can use them.
1
2
3
4
Location::Location(int loc_x, int loc_y)
{
    // what should you do in here? 
}


am I correct in saying that loc1 and loc2 are actually names of objects created from the Location object, instantiations of Location

Well, not 'exactly'. As you have it right now, they are pointers to objects of type Location.
You don't need to use new here.
If you said
1
2
Location loc1(30, 10);
Location loc2(20, 20);

Then, loc1 and loc2 would instantiations (objects) of Location.
Last edited on
the main.cpp was given to me and the member functions definitions were also given to me. I can't change anything because it's going to be marked by an automaker and if I change things it's going to error.

But thanks for the clarification, will see what I can do.
Let's clarify something here. The variable names loc1 and loc2 are used in 2 different contexts with 3 completely different meanings.

In the inherited main() function, they are pointers to Location objects. In @Ganado's most recent post, they are objects of type Location (not pointers).

However, in your computeDistance function, they are float values that are actually differences between the x (or y) coordinates of the two locations. These are the variables that I think should be renamed.

I'm a serious c++ noob so I'm definitely making stupid mistakes.

Understood. But you are letting your noobness cloud your thinking about the problem. This program just does simple algebra in a 2-dimensional space.

In 2D math, each point has an X value and a Y value. Together, (X, Y) represents a point in space. You are creating a class "Location" to capture this concept. Each Location object contains an X value and a Y value, thus representing a point in 2D space.

When you construct a Location (a point), you give it initial values. So, Location(10, 10) means you want a point at coordinate (10, 10). However, you need to write the code that assigns these values. Your suggested code
1
2
3
4
5
Location::Location(int, int)
{
    x = 10;
    y = 89;
}

always stores the values 10 and 89, so all Locations will be identical. That's why you need to capture the arguments with names and use them in the constructor body like @Ganado suggested and I previously showed you.

In 2D math, the distance between 2 points is sqrt(dx^2 + dy^2). But in order to get dx and dy, you need 2 points. Your computeDistance function is a member of the Location class, so when you call it, the object you call it on is already known. The argument passed in is the 2nd Location. So, with the call loc1.computeDistance(loc2), [or, with pointers, loc1->computeDistance(*loc2) ], you are calculating the distance between loc1 (the object on which you are calling the function) and loc2 (the argument).

The key is to understand the math that you are trying do do and then figure out how to put it into code. If you can't clearly understand the underlying math, you will end up confused and guessing.
Last edited on
That makes sense. Thanks doug4 and all who pitched in. I'll put your suggestions into practise and see what I can come up with. I'm sure I've overcomplicated this task.
I got it to work, thanks everybody
Topic archived. No new replies allowed.