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
If you want to be very mathematical, maybe this can help: https://en.wikipedia.org/wiki/Homogeneous_coordinates
In 2d that means a position is (x,y,1) and a direction (dx,dy,0). The reason for this is projection, which is rare in 2d but common in 3d.
So to try to answer: Just use 4 component vectors all the time. Positions have a w=1, directions a w=0.
Just try it with a line based of two points A and B, both have w=1. The vector from A to B is B-A, which ends up with w=0.
Also what you use in your code does matter very little unless you end up optimizing a special case. Just go for the smallest data structure. Start and end should be fine.
Maybe think about indexed: A flat array of all vertices and every line is just two indices into the vertex array.
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.
Use the representation of line segments you have in the question.
I'll write LS(a,b)
for the line segment with start point a
, and, end point b
.
Now given two such segments LS(a,b)
, and, LS(c,d)
that intersect (in your context one from the clipping polygon and one from the polygon being clipped; I am presuming you know how to determine this).
What you seem to want answered is if this intersection has LS(c,d)
going to the inside of the polygon while crossing the edge LS(a,b)
.
For this, it is sufficient to determine the angle between the directions of the line segments. This is the same as the angle between the vectors v = b-a
and w = d-c
.
Also, you don't even need the angle, all you need is to see if the angle is positive or negative; so look at the vector w-v
. If LS(c,d)
crosses LS(a,b)
to the inside, this vector will be in the lower half plane. If LS(c,d)
crosses LS(a,b)
to the outside, this vector will be in the upper half plane.
Determining upper verses lower half plane means looking at the second coordinate of end-start
.
Apologies for the wall of text, but mathjax doesn't seem active on this site. Also no code, but I believe that (if I didn't make any mistakes) all the operations I mentioned are easy to translate into code.
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;
}
};
If you want to convert a line segment to a vector, you have to be aware that there is no "universal semantic" for the conversion, it is up to you to define what the conversion means. That said, I assume you want a vector with the same (Euclidean) norm as the length of the line segment and pointing in the same direction, i.e. something like this:
class LineSegment2d
{
....
Vector2d getVector() const {
return Vector2d(end) - Vector2d(start);
}
};
In other words, offset the line segment to the origin point of the coordinate system. The end point can then be converted to a vector.
EDIT: After understanding a bit more about why you want this, you might be looking for another representation
class LineSegment2d
{
....
Vector2d getVector() const {
return Vector2d(end);
}
};
This will get you one vector for each line segment: the end point. If your polygons consist of connected line segments, this will give you all the vertices in the polygon.
Your representation of class LineSegment2d
is fine. But the representation of class Vector2d
is incorrect. This is because you are considering only those vectors that pass through the origin. A vector on a 2d plane can be represented with 3 components in the same way it done in 3d space. The 3 components of a vector are namely: Direction, Magnitude and A point through which it passes. If we define x, y and z axes for a 3d space then, for a point in the x-y plane z component is equal to 0. Also, direction in 3d space is defined in the form of direction cosines(ie. the cosine of the angle between the vector and an axis). Hence cosine of angle between vector and z-axis is equal to zero(because the angle = 90 degrees) for a vector in x-y plane.