Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I represent a vector equation of a line segment in C++?

I am working with computer graphics.

I would like to represent a line with two end points, and, then I would like my Line2d class to have a method that returns a Vector2d object.

Suppose, I have the following classes:

struct Point2d
{
    int x;
    int y;
};

Then, I can easily represent a line segment using two points:

class LineSegment2d
{
private:
    Point2d start;
    Point2d end;
public:
    ...
    ...
};

According to the definition, a vector is composed of a magnitude and a direction.

class Vector2d
{
private:
    Point2d p;
public:
    double Magnitude(void);
    Point Component(void);
    Vector2d Normal();
    Vector2d & Add(Vector & rhs);
    Vector2d & Subtract(Vector & rhs);
    Vector2d & Multiply(int scalar);
    int DotProduct(Vector2d rhs);
    Vector2d & CrossProduct(Vector2d rhs);
};

One object of Point2d is sufficient to represent a vector. For example, magnitude of a vector = sqrt(p.x*p.x + p.y*p.y);. And, p.x and p.y collectively represent the direction.


On the other hand, we know that the vector equation of a line passing through (x0,y0,z0) is, r =r0 + tv Where, r is the vector for the subject line. r0 is a position vector that points to the direction of the point (x0, y0, z0). Since, r0 is a position vector, obviously, the origin of r0 would be (0,0,0). t is any real numbered value, where, −∞<t<∞ –. v is a vector which is parallel to our subject straight line.

Vector equation of a line segment between the points P(1, 3, 2) and Q(-4, 3, 0):

According to the above formula, the vector equation of the line PQ could be either

r =<1,3,2> + tv 

or,

r =<-4,3,0> + tv

The vector that connects the two points P and Q is,

PQ  = <(-4-1), (3-3), (0-2)>
    = <-5, 0, -2>

And, this vector is parallel to our subject line for sure.

So, we can write,

r   =<1, 3, 2> + t <-5, 0, -2>
    =<1, 3, 2>+<-5t, 0, -2t>
    = <(1-5t), (3+0), (2-2t)>
    =<1-5t, 3, 2-2t>

According to the vector equation of a line segment, I think, my Vector class should look like the following:

class LineVector2d
{
private:
    Vector2d v;
    double t;
public:
    ..........
};

Is this the correct representation?

If that so, how can I calculate/set/find the value of t?

like image 281
user366312 Avatar asked Feb 09 '23 15:02

user366312


2 Answers

There are many forms of line representation.

If you mean line (not segment), then, probably, you'll find convenient to use class/structure, containing BasePoint and UnitDirectionVector.

For line segments, choose between (Point pt0, Point pt1) form, and, (Point pt, Vector v = pt1 - pt0) form.

The second one is more suitable for parametric approach like, X = P0.X + t * D.X etc.

like image 78
MBo Avatar answered Feb 12 '23 04:02

MBo


I think there's some confusion because of the following

According to the definition, a vector is composed of a magnitude and a direction.

There is more than one way of representing a vector. I think in your question you mean that a vector can be represented by a magnitude (scalar) and a unit vector indicating a direction. A vector can just be an ordered triplet (for three dimensions) that indicate the magnitude (sqrt(x^2 + y^2 + z^2)) and the direction from the origin.

I think the answer to your question is, you don't need to calculate t. Correct me if I'm mistaken, but I think you're interpreting t as the magnitude? You can calculate that from v with sqrt(x^2 + y^2 + z^2), but v can hold both a magnitude and direction as an ordered triplet by itself.

Edit:

template <typename T>
struct Point2d
{
    T x;
    T y;

    Point2d operator + (const Point2d<T>& rhs) const
    {
        return Point2d<T>{x + rhs.x, y + rhs.y};
    }
    Point2d operator - (const Point2d<T>& rhs) const
    {
        return Point2d<T>{x - rhs.x, y - rhs.y};
    }
    // ...

    Point2d operator * (const T value) const
    {
        return Point2d<T>{x*value, y*value};
    }
    Point2d operator / (const T value) const
    {
        return Point2d<T>{x/value, y/value};
    }
    // ...
};

template <typename T>
class Vector2d
{
private:
    Point2d<T> p;
public:
    Vector2d(const Point2d<T>& point) : p{point} {}

    /*double Magnitude();
    Point2d<T> Component();
    Vector2d Normal();
    int DotProduct(Vector2d rhs);
    Vector2d& CrossProduct(Vector2d rhs);*/

    Vector2d operator + (const Vector2d<T>& rhs) const
    {
        return p + rhs.p;
    }
    Vector2d operator - (const Vector2d<T>& rhs) const
    {
        return p - rhs.p;
    }
    // ...

    Vector2d operator * (const T value) const
    {
        return p*value;
    }
    Vector2d operator / (const T value) const
    {
        return p/value;
    }
    // ...
};

template <typename T>
class LineVector2d
{
private:
    Point2d<T>  p;
    Vector2d<T> v;

public:
    LineVector2d() = default;
    LineVector2d(const Point2d<T>& point, const Vector2d<T>& direction) : p{point}, v{direction} {}

    /// Returns the point on the line for the time/value `t`
    Point2d<T> valueAt(T t)
    {
        return p + v*t;
    }
};
like image 42
R2-Dequeue Avatar answered Feb 12 '23 05:02

R2-Dequeue