有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java需要一个函数来限制一条线(通过它的坐标知道)的长度

我需要一个函数,它取一条线(通过它的坐标知道) 并返回一条角度相同但长度有限的线

“我的代码”仅在该行变为“右”时提供正确的值
(抱歉,这只是经验证明的)

我错过什么了吗

public static double getAngleOfLine(int x1, int y1, int x2, int y2) {
  double opposite = y2 - y1;
  double adjacent = x2 - x1;

  if (adjacent == Double.NaN) {
    return 0;
  }

  return Math.atan(opposite / adjacent);
}

// returns newly calculated destX and destY values as int array
public static int[] getLengthLimitedLine(int startX, int startY,
    int destX, int destY, int lengthLimit) {

  double angle = getAngleOfLine(startX, startY, destX, destY);

  return new int[]{
        (int) (Math.cos(angle) * lengthLimit) + startX,
        (int) (Math.sin(angle) * lengthLimit) + startY
      };
}

顺便说一句:我知道用Java返回数组是愚蠢的, 但这只是一个例子


共 (6) 个答案

  1. # 1 楼答案

    把它当作一个向量会更容易。通过除以其大小,然后乘以所需长度的因子,对其进行归一化

    然而,在你的例子中,试试数学。atan2

  2. # 2 楼答案

    不需要使用trig,它可能会有一些令人讨厌的边缘情况。只需使用类似的三角形:

    public static int[] getLengthLimitedLine(int startX, int startY,
        int destX, int destY, int lengthLimit)
    {
        int deltaX = destX - startX;
        int deltaY = destY - startY;
        int lengthSquared = deltaX * deltaX + deltaY * deltaY;
        // already short enough
        if(lengthSquared <= lengthLimit * lengthLimit)
            return new int[]{destX, destY};
    
        double length = Math.sqrt(lengthSquared);
        double newDeltaX = deltaX * lengthLimit / length;
        double newDeltaY = deltaY * lengthLimit / length;
    
        return new int[]{(int)(startX + newDeltaX), (int)(startY + newDeltaY)};
    }
    
  3. # 3 楼答案

    在类中封装行,添加一个unit方法和一个scale方法

    public class Line {
    private float x;
    private float y;
    
    public Line(float x1, float x2, float y1, float y2) {
        this(x2 - x1, y2 - y1);
    }
    
    public Line(float x, float y) {
        this.x = x;
        this.y = y;
    }
    
    public float getLength() {
        return (float) Math.sqrt((x * x) + (y * y));
    }
    
    public Line unit() {
        return scale(1 / getLength());
    }
    
    public Line scale(float scale) {
        return new Line(x * scale, y * scale);
    
    }
    }
    

    现在你可以通过调用

    Line result = new Line(x1, x2, y1, y2).unit().scale(l);
    
  4. # 4 楼答案

    在Python中,因为我手头没有Java编译器:

    import math
    
    def getLengthLimitedLine(x1, y1, x2, y2, lengthLimit):
        length = math.sqrt((x2-x1)**2 + (y2-y1)**2)
        if length > lengthLimit:
           shrink_factor = lengthLimit / length
           x2 = x1 + (x2-x1) * shrink_factor
           y2 = y1 + (y2-y1) * shrink_factor
        return x2, y2
    
    print getLengthLimitedLine(10, 20, 25, -5, 12)
    # Prints (16.17, 9.71) which looks right to me 8-)
    
  5. # 5 楼答案

    只需使用Pythagorean theorem,如下所示:

    public static int[] getLengthLimitedLine(int start[], int dest[], int lengthLimit) {
        int xlen = dest[0] - start[0]
        int ylen = dest[1] - start[1]
        double length = Math.sqrt(xlen * xlen + ylen * ylen)
    
        if (length > lengthLimit) {
            return new int[] {start[0], start[1],
                    start[0] + xlen / lengthLimit,
                    start[1] + ylen / lengthLimit}
        } else {
            return new int[] {start[0], start[1], dest[0], dest[1];}
        }
    }
    
  6. # 6 楼答案

    如果你了解向量,这是一个很容易的问题

    给定两点(x1,y1)和(x2,y2),可以计算从点1到点2的矢量:

    v12=(x2-x1)i+(y2-y2)j

    其中i和j是x和y方向上的单位向量

    可以通过取组件平方和的平方根来计算v的大小:

    v=sqrt((x2-x2)^2+(y2-y1)^2)

    从点1到点2的单位向量等于v12除以其大小

    考虑到这一点,你可以通过将单位向量乘以长度,并将其加到点1,来计算出单位向量上的点,即所需距离