首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >反射线上用矩阵反射2d点

反射线上用矩阵反射2d点
EN

Stack Overflow用户
提问于 2017-01-07 20:20:39
回答 2查看 1.4K关注 0票数 0

给定任意反射线,如何用矩阵反射一组点?我试过以下几种方法,但我无法使它发挥作用:

  1. 转换系统,使反射线的P1位于原点。
  2. 旋转系统,使反射线与Y平行 轴心
  3. 执行Y轴反射
  4. 撤销旋转
  5. 撤消翻译

我试着用C#写一种方法来做这件事,基本上,我给它线的两点,然后得到矩阵。

EN

回答 2

Stack Overflow用户

发布于 2017-01-07 23:43:29

有一个公式可以反映通过原点的任何一条线。以来,不需要进行轮调。让(a,b)(c,d)是反射线上的任何两点的。假设您想要反映的是(x,y)

  1. 转换坐标,使(a,b)成为原点。然后(x,y)变成(x-a,y-b)。这一步只是向量减法。
  2. 反省。这是你需要矩阵的地方你将把矩阵乘以步骤1中转换的向量,你的结果将是另一个向量(2乘1矩阵)。
  3. 将坐标转换回原来的系统。这是步骤1的反义词,也就是说,这是向量加法,从步骤1中取消向量减法。在这个步骤中,您只是将(a,b)添加到步骤2的结果中。

步骤2的矩阵是:

代码语言:javascript
复制
H(θ) = [cos(2θ)   sin(2θ)]
       [sin(2θ)  -cos(2θ)]

在矩阵中,θ是(平移的)反射线与正x轴相交的角度。只要ac不相等,就可以通过计算来找到θ:

代码语言:javascript
复制
θ = arctangent( (d-b) / (c-a) )

您将严格地在-π/2π/2之间得到一个值。如果是a = c,也就是说,如果反射线是垂直的,那么就取θ = π/2。尽管如果反射线是垂直的(或者是水平的,在这种情况下是θ = 0),那么您可以只使用众所周知的反射矩阵来在y轴或x轴上进行反射。

这在很大程度上展示了寻找和使用矩阵的整个过程。听起来你只想要找到反射矩阵。我不太了解C#,无法在回答中使用它,但下面是伪代码:

代码语言:javascript
复制
// (a,b) and (c,d) are any two distinct points on the reflection line
getMatrix(double a, double b, double c, double d)
    double x11, x12, x21, x22;  // Elements of the reflection matrix

    if a == c  // If the reflection line is vertical
        x11 = -1; x12 = 0; x21 = 0; x22 = 1;
    else if b == d  // If the reflection line is horizontal
        x11 = 1; x12 = 0; x21 = 0; x22 = -1;
    else
        double θ = arctangent( (d-b) / (c-a) );

        x11 = cos(2 * θ);
        x12 = sin(2 * θ);
        x21 = x12;  // sin(2 * θ) again
        x22 = -x11;  // -cos(2 * θ)
    end if

    return Matrix(x11, x12, x21, x22);
    /*  The above line returns a matrix with the following entries:
          [ x11  x12 ]
          [ x21  x22 ]
    */

下面是使用上述伪码的伪代码示例:

代码语言:javascript
复制
// Reflect (x,y) over the line given by the points (a,b) and (c,d)
reflectPoint(double x, double y, double a, double b, double c, double d)
    Matrix reflector = getMatrix(a, b, c, d);
    Vector v1 = new Vector(x-a, x-b);  // This is Step 1
    Vector v2 = new Vector(a, b);      // This is so we can do Step 3 later

    return reflector * v1 + v2;  // v1 already has Step 1 done
                                 // reflector * v1 is Step 2
                                 // + v2 is Step 3

有更有效的方法来完成上面的工作(例如,检查给定的点之一(a,b)(c,d)是否已经是原点),但是上面的方法仍然有效。

票数 2
EN

Stack Overflow用户

发布于 2017-01-08 12:02:43

在修复了我在这里所做的错误后,我的代码如下所示:

代码语言:javascript
复制
private Transformer2D Reflect(Vector2D p1, Vector2D p2)
{
        var translationMatrix = new TranslateTransformation2D(new Vector2D(0, 0) - p1);
        var inverseTranslationMatrix = new TranslateTransformation2D(p1);
        var translatedP2 = translationMatrix.Transform(p2); //What p2 would be if p1 of the line was translated to the origin.
        var angleWithYaxis = new Vector2D(0, 1).AngleBetweenTwoVectors(translatedP2);
        var rotationMatrix = new RotationTransformation2D(-angleWithYaxis * RhinoMath.Deg2Rad);
        var inverseRotationMatrix = new RotationTransformation2D(angleWithYaxis * RhinoMath.Deg2Rad);
        var reflectionMatrix = new ScaleTransformation2D(-1, 1);
        return new Transformer2D(translationMatrix, rotationMatrix, reflectionMatrix, inverseRotationMatrix, inverseTranslationMatrix);
}

iam类只使用抽象的矩阵:

代码语言:javascript
复制
public class TranslateTransformation2D : MatrixTransformation2DBase
{
    public TranslateTransformation2D(Vector2D translation)
    {
        TransformationMatrix = Matrix3x3.CreateTranslationMatrix(translation.X, translation.Y);
    }

    public TranslateTransformation2D(float x, float y)
    {
        TransformationMatrix = Matrix3x3.CreateTranslationMatrix(x, y);
    }
}

Matrix3x3类如下所示:

代码语言:javascript
复制
public class Matrix3x3 : Matrix
{
    public Matrix3x3(double m11, double m12, double m13,
                     double m21, double m22, double m23,
                     double m31, double m32, double m33)
    {
        Rows = 3;
        Cols = 3;
        Mat = new double[Rows * Cols];
        Mat[0] = m11;
        Mat[1] = m12;
        Mat[2] = m13;

        Mat[3] = m21;
        Mat[4] = m22;
        Mat[5] = m23;

        Mat[6] = m31;
        Mat[7] = m32;
        Mat[8] = m33;
    }

    public static Matrix3x3 CreateTranslationMatrix(double x, double y)
    {
        return new Matrix3x3(1, 0, x,
                             0, 1, y,
                             0, 0, 1);
    }

    public static Matrix3x3 CreateScaleMatrix(double x, double y)
    {
        return new Matrix3x3(x, 0, 0,
                             0, y, 0,
                             0, 0, 1);
    }

    public static Matrix3x3 CreateIdentityMatrix()
    {
        return new Matrix3x3(1, 0, 0,
                             0, 1, 0,
                             0, 0, 1);
    }

    public static Matrix3x3 CreateRotationMatrix(double radians)
    {
        var cos = Math.Cos(radians);
        var sin = Math.Sin(radians);

        return new Matrix3x3(cos, -sin, 0,
                             sin, cos, 0,
                             0, 0, 1);

    }

Transformer2D类在这里是特殊的,因为它简单地将所有的转换组合成一个矩阵,所以我们只需要应用这个矩阵就可以得到所有的转换:

代码语言:javascript
复制
public class Transformer2D : MatrixTransformation2DBase
{
    public Transformer2D(params IMatrixTransformation2D[] transformations)
    {
        for (int i = transformations.Length - 1; i >= 0; i--)
        {
            var matrixTransformation2D = transformations[i];
            if (TransformationMatrix != null)
            {
                TransformationMatrix = TransformationMatrix * matrixTransformation2D.TransformationMatrix;
            }
            else
            {
                TransformationMatrix = matrixTransformation2D.TransformationMatrix;
            }
        }
    }
}

MatrixTransformation2DBase类

代码语言:javascript
复制
public abstract class MatrixTransformation2DBase : IMatrixTransformation2D
{
    public Matrix3x3 TransformationMatrix { get; protected set; }

    public Vector2D Transform(Vector2D vector2Din)
    {
        return vector2Din*TransformationMatrix;
    }
}

我可能会在一些地方使它更快,但我的想法是,我不必再担心矩阵本身,除非我想要一些新的类型的转换。

对于那些想知道我在内部使用什么矩阵类的人,它是这样的:https://github.com/darkdragon-001/LightweightMatrixCSharp

我所做的只是写了一些关于这件事的信息。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41526113

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档