Calculate a point along the line A-B at a given distance from A

前端 未结 6 1378
情歌与酒
情歌与酒 2020-11-29 08:54

I\'m going quite mad trying to calculate the point along the given line A-B, at a given distance from A, so that I can "draw" the line between two given points. It

6条回答
  •  既然无缘
    2020-11-29 09:27

    Calculate the vector AB

    First define the vector from point A(1,-1) to point B(2,4) substracting A from B. The vector would be Vab(1,5).

    Calculate the length of AB

    Use Pythagorean theorem to calculate the length of vector AB.

    |Vab| = SQRT(1²+5²)
    

    The Length is (rounded) 5.1

    Calculate the unit vector

    Divide the vector by its length to get the unit vector (the vector with length 1).

    V1(1/5.1,5/5.1) = V1(0.2, 0.98)
    

    Calculate the vector with length 4

    Now multiply V1 with the length you want, for example 4, to get Vt.

    Vt(0.2*4,0.98*4) = Vt(0.8,3.92)
    

    Calculate target point

    Add the vector Vt to point A to get point T (target).

    T = A + Vt = T(1.8,2.92)
    

    EDIT: Answer to your edit

    The method LengthOfHypotenuse should look like that

    • fixed an error on calculating bSq
    • and removed redundant Math.Abs call, because a pow of 2 is always positive
    • removed the addition of 0.5, don't know why you would need that
    • you should at least use a float as return value (double or decimal would work also)

      //You should work with Vector2 class instead of Point and use their Length property
      private double LengthOfHypotenuse(Point a, Point b) {
          double aSq = Math.Pow(a.X - b.X, 2); // horizontal length squared
          double bSq = Math.Pow(a.Y - b.Y, 2); // vertical length  squared
          return Math.Sqrt(aSq + bSq); // length of the hypotenuse
      }
      

    The method Draw(Point a, Point b) should look like that:

    • Corrected DrawCell() call

      private void Draw(Point a, Point b) {
          double maxDistance = LengthOfHypotenuse(a, b);
          for (int distance = 0; distance < maxDistance; ++distance) {
              var point = CalculatePoint(new Vector2(a), new Vector2(b), distance);
              DrawCell(point.X, point.Y, _theLineBrush);
          }
      }
      

    Your CalculatePoint(Point a, Point b, int distance) method:

    • Moved some calculations into Vector2 class

      private Point CalculatePoint(Vector2 a, Vector2 b, int distance) {
          Vector2 vectorAB = a - b;
      
          return a + vectorAB.UnitVector * distance;
      }
      

    I have extended the Vector class for you to add the missing operators (credits to AgentFire)

        //AgentFire: Better approach (you can rename the struct if you need):
        struct Vector2 {
            public readonly double X;
            public readonly double Y;
            public Vector2(Point p) : this(p.X,p.Y) { 
            }
    
            public Vector2(double x, double y) {
                this.X = x;
                this.Y = y;
            }
            public static Vector2 operator -(Vector2 a, Vector2 b) {
                return new Vector2(b.X - a.X, b.Y - a.Y);
            }
            public static Vector2 operator +(Vector2 a, Vector2 b) {
                return new Vector2(b.X + a.X, b.Y + a.Y);
            }
            public static Vector2 operator *(Vector2 a, double d) {
                return new Vector2(a.X * d, a.Y * d);
            }
            public static Vector2 operator /(Vector2 a, double d) {
                return new Vector2(a.X / d, a.Y / d);
            }
    
            public static implicit operator Point(Vector2 a) {
                return new Point((int)a.X, (int)a.Y);
            }
    
            public Vector2 UnitVector {
                get { return this / Length; }
            }
    
            public double Length {
                get {
                    double aSq = Math.Pow(X, 2);
                    double bSq = Math.Pow(Y, 2);
                    return Math.Sqrt(aSq + bSq);
                }
            }
    
            public override string ToString() {
                return string.Format("[{0}, {1}]", X, Y);
            }
        }
    

提交回复
热议问题