我正在使用计算机图形。

我想用两个端点表示一条线,然后我希望我的 Line2d 类有一个返回 Vector2d 对象的方法。

假设,我有以下类(class):

struct Point2d
{
    int x;
    int y;
};

然后,我可以使用两点轻松表示线段:
class LineSegment2d
{
private:
    Point2d start;
    Point2d end;
public:
    ...
    ...
};

根据定义, vector 由大小和方向组成。
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 的一个对象足以表示一个 vector 。例如, vector 的大小 = sqrt(p.x*p.x + p.y*p.y); 。并且,p.xp.y 共同代表方向。

另一方面,我们知道通过 (x0,y0,z0) 的线的 vector 方程是,r =r0 + tv在哪里,r 是主题行的 vector 。r0 是一个位置 vector ,指向点 (x0, y0, z0) 的方向。由于 r0 是一个位置 vector ,显然, r0 的原点将是 (0,0,0)t 是任何实数,其中 −∞<t<∞ –v 是一个与我们的主题直线平行的 vector 。
P(1, 3, 2)Q(-4, 3, 0) 点之间线段的 vector 方程:

根据上面的公式,PQ 线的 vector 方程可以是
r =<1,3,2> + tv

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

连接两点 PQ 的 vector 是,
PQ  = <(-4-1), (3-3), (0-2)>
    = <-5, 0, -2>

而且,这个 vector 肯定与我们的主题平行。

所以,我们可以写,
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 方程,我认为,我的 Vector 类应该如下所示:
class LineVector2d
{
private:
    Vector2d v;
    double t;
public:
    ..........
};

这是正确的表示吗?

如果是这样,我如何计算/设置/找到 t 的值?

最佳答案

我认为由于以下原因存在一些混淆



表示 vector 的方法不止一种。我认为在您的问题中,您的意思是 vector 可以用幅度(标量)和指示方向的单位 vector 表示。一个 vector 可以只是一个有序的三元组(对于三个维度),表示大小( sqrt(x^2 + y^2 + z^2) )和从原点开始的方向。

我认为您的问题的答案是,您不需要计算 t 。如果我弄错了,请纠正我,但我认为您将 t 解释为幅度?您可以使用 vsqrt(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;
    }
};

10-07 19:06
查看更多