判断一个点是否在指定的直角三角形内

《Java 语言程序设计与数据结构》(基础篇)练习题 3.27

题目:
假设一个平面上有一个直角三角形,如下图所示。直角点在(0,0)处,其他两个点分别在(200,0)和(0,100)处。编写程序,提示用户输入一个点的 x 坐标和 y 坐标,然后判断这个点是否在该三角形内。下面是运行示例:

Enter a point's x- and y-coordinates: 100.5 25.5
The point is in the triangle

Enter a point's x- and y-coordinates: 100.5 50.5
The point is not in the triangle


解题思路

首先,如果一个点位于这个三角形内,则它肯定是属于下图中的两条虚线包含的范围之内。也就是这个直角三角形的斜边和把斜边平移到穿过原点时候的位置。

右下角的直角那一侧很好判断,只需要判断点的横纵坐标是否都大于 0 (条件1)即可,难的地方在这个点是否超出了这条斜边。

可以从“截距”方面入手。关于截距的概念可以参考这里。截一个简单的解释:

根据上面的解释,现在这条斜边的截距是 100,那么可以把这条斜边平移到点上。如果平移后直线的截距大于等于 0 并且小于等于 100,那么这个点就是位于三角形内(当然是在条件1成立的前提下),否则就是位于三角形外。

于是问题就变成了求截距

前面讲了,既然线是平移的,因此平移后的线和平移前的线它们的斜率是相同的。而且明显,这条直线是个二元一次方程。也就是 y = kx + b 的形式。我们可以根据斜边的两个端点来求得这个斜率。

k = (y2 - y1) / (x2 - x1) = (100 - 0) / (0 - 200) = -0.5

得到这条斜边的斜率是 -0.5,而它的截距是 100,所以这条斜边的方程式就是 y = -0.5x + 100。(当然这个不重要)

那么平移之后的直斜的截距就很好算了。因为截距相同,所以把截距代入二元一次方程,可得 y = -0.5x + b。再把要计算的点的坐标代入,就可以得到 b 的值,也就是截距的值了。再判断这个截距是否在 0-100 范围内即可。

Java 代码如下:

import java.util.Scanner;

public class Practice27 {
    public static void main(String[] args) {
        System.out.println("Enter a point's x- and y-coordinates:");
        Scanner input = new Scanner(System.in);
        double x = input.nextFloat();
        double y = input.nextFloat();

        // 先判断用户输入的点有没有超出范围(这里实际上是一个矩形区域)
        boolean flag = (!(x < 0) && !(x > 200)) && (!(y < 0) && !(y > 100));

        // 根据斜率算用户所输入的点的截距
        double k = (100.0 - 0) / (0 - 200);  // 先求斜率
        double b = y  - k * x;                // 原公式是 y = kx + b 稍微移位一下,就可以得到截距 b = y - kx
        if (b < 0 || b > 100) {
            flag = false;
        }

        if (flag) {
            System.out.println("The point is in the triangle");
        } else {
            System.out.println("The point is not in the triangle.");
        }
    }
}
posted @ 2022-06-15 22:57  东围居士  阅读(351)  评论(0编辑  收藏  举报