我正在使用计算机图形学。
我想用两个端点表示一行,然后我希望我的Line2d
类有一个返回Vector2d
对象的方法。
假设我有以下几个类:
struct Point2d
{
int x;
int y;
};
然后,我可以使用两个点轻松表示一个线段:
class LineSegment2d
{
private:
Point2d start;
Point2d end;
public:
...
...
};
根据定义,矢量由幅度和方向组成。
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);
};
Point2d
的一个对象足以表示向量。例如,向量的大小= sqrt(p.x*p.x + p.y*p.y);
。并且,p.x
和p.y
共同代表了方向。
另一方面,我们知道通过(x0,y0,z0)
的直线的矢量方程为r =r0 + tv
哪里,
r
是主题行的向量。
r0
是一个位置向量,指向点(x0, y0, z0)
的方向。由于r0是位置向量,显然r0的原点是(0,0,0)
。
t
是任何实数编号的值,其中−∞<t<∞ –
。
v
是一个与我们的主题直线平行的向量。
点P(1, 3, 2)
和Q(-4, 3, 0)
之间的线段的矢量方程:
根据上面的公式,线PQ
的矢量方程可以是
r =<1,3,2> + tv
或,
r =<-4,3,0> + tv
连接两个点P
和Q
的向量是
PQ = <(-4-1), (3-3), (0-2)>
= <-5, 0, -2>
而且,这个向量肯定与我们的主题行平行。
所以,我们可以写,
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>
根据线段的矢量方程,我认为,我的Vector类应该如下所示:
class LineVector2d
{
private:
Vector2d v;
double t;
public:
..........
};
这是正确的表示吗?
如果是这样,我如何计算/设置/找到t
的值?
答案 0 :(得分:4)
有many forms of line representation。
如果你的意思是行(不是段),那么,你可能会发现使用包含BasePoint和UnitDirectionVector的类/结构很方便。
对于线段,请选择(Point pt0, Point pt1
)表单和(Point pt, Vector v = pt1 - pt0
)表单。
第二个更适合参数化方法,如,
X = P0.X + t * D.X
等。
答案 1 :(得分:1)
如果要将线段转换为矢量,则必须注意转换没有“通用语义”,您可以自行定义转换的含义。也就是说,我假设你想要一个具有相同(欧几里得)范数的向量作为线段的长度并指向相同的方向,即类似这样的东西:
class LineSegment2d
{
....
Vector2d getVector() const {
return Vector2d(end) - Vector2d(start);
}
};
换句话说,将线段偏移到坐标系的原点。然后可以将终点转换为矢量。
编辑:在了解了你想要这个的原因之后,你可能正在寻找另一种表现形式
class LineSegment2d
{
....
Vector2d getVector() const {
return Vector2d(end);
}
};
这将为每个线段提供一个向量:终点。如果您的多边形由连接的线段组成,则会为您提供多边形中的所有顶点。
答案 2 :(得分:1)
使用问题中的线段表示。
我会为包含起点LS(a,b)
和终点a
的线段写b
。
现在给出两个这样的段LS(a,b)
和LS(c,d)
相交(在你的上下文中,一个来自剪裁多边形,一个来自被剪裁的多边形;我假设你知道如何确定这个) 。
您似乎想要回答的是,如果此交叉点在穿过边LS(c,d)
时LS(a,b)
到达多边形内部。
为此,确定线段方向之间的角度就足够了。这与向量v = b-a
和w = d-c
之间的角度相同。
此外,你甚至不需要角度,你只需要看角度是正还是负;所以看看向量w-v
。如果LS(c,d)
越过LS(a,b)
到内部,则此向量将位于下半平面中。如果LS(c,d)
与LS(a,b)
交叉到外部,则此向量将位于上半平面中。
确定下半平面的上半部分意味着查看end-start
的第二个坐标。
为文本墙道歉,但mathjax在此网站上似乎不活跃。也没有代码,但我相信(如果我没有犯任何错误)我提到的所有操作都很容易翻译成代码。
答案 3 :(得分:1)
如果你想要非常数学,也许这会有所帮助:https://en.wikipedia.org/wiki/Homogeneous_coordinates
在2d中,这意味着位置是(x,y,1)和方向(dx,dy,0)。其原因是投影,这在2d中很少见,但在3d中很常见。
所以试着回答:一直使用4个分量向量。位置w = 1,方向a w = 0。
尝试使用基于两点A和B的线,两者都有w = 1。从A到B的向量是B-A,其最终为w = 0。
除非您最终优化特殊情况,否则您在代码中使用的内容确实很重要。只需寻找最小的数据结构。开始和结束应该没问题。
也许想想索引:所有顶点的平面数组和每一行只是顶点数组中的两个索引。
答案 4 :(得分:1)
我认为由于以下内容存在一些混淆
根据定义,矢量由幅度和方向组成。
表示矢量的方法不止一种。我认为在你的问题中,你的意思是矢量可以用幅度(标量)和表示方向的单位矢量来表示。向量可以只是一个有序的三元组(三维),表示幅度(sqrt(x^2 + y^2 + z^2)
)和来自原点的方向。
我认为你的问题的答案是,你不需要计算t
。如果我弄错了,请纠正我,但我认为你将t
解释为量级?您可以使用v
从sqrt(x^2 + y^2 + z^2)
计算出来,但v
可以将量值和方向同时保持为有序三元组。
修改强>
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;
}
};
答案 5 :(得分:0)
您对班级LineSegment2d
的陈述很好。但是类Vector2d
的表示是不正确的。这是因为您只考虑那些通过原点的矢量。 2d平面上的矢量可以用与3d空间中相同的方式用3个分量表示。矢量的3个分量是:方向,幅度和它通过的A点。如果我们为3d空间定义x,y和z轴,那么对于xy平面中的一个点,z分量等于0.此外,3d空间中的方向以方向余弦的形式定义(即,余弦的余弦。矢量和轴之间的角度)。因此,对于x-y平面中的向量,向量和z轴之间的角度余弦等于零(因为角度= 90度)。