一、项目进度

今天终于把不规则区域的点击判定给实现了,之前想用map标签来做,这在网页上是可行的,但是uni-app把map做成了一个地图组件,功能和HTML中的完全不同,没法进行不规则区域定位,于是采用了下面的办法

二、使用方程组,结合点击坐标进行不规则区域的判定

用户点击屏幕时会把点击事件的信息存在event中,我们可以通过event来获取用户点击屏幕的哪个位置,再来做出不规则区域的判定

首先,通过打印输出event事件,可以发现x、y坐标的信息存在touches数组中,并且内外盒子获取的点击坐标相同,说明坐标针对的是整个屏幕

时钟图片:

其次,我们要知道点击发生在哪个区域,就要先把这个区域表示出来,然后看点击的坐标是否在这个区域内,观察时钟图片可以发现每个区域由三条线构成,两条斜线+一条弧线,它们都可以用方程表示,但要先知道12个时刻点和圆点中心的坐标,于是先打印输出0点到3点的坐标:

0 (186,130),

1 (260,148),

2 (318,203),

3 (336,273),

再根据时钟的对称性,补齐剩余坐标(这样做的好处是坐标点互相验证,不容易发生错误):

4 (318,343),

5 (260,394),

6 (186,412),

7 (112,394),

8 (54,343),

9 (36,273),

10 (54,203),

11 (112,148),

中心圆点 (186,273)

接下来,我们需要得到代表每个区域的方程组

最外层圆的方程比较容易得到,只需要知道圆心坐标和半径即可:(X-186)²+(y-273)²<=143²

剩余12个直线的方程,可以用直线上的两个坐标带入得到点斜式计算,但是一个个算太麻烦了,而且容易出错,我就写了个程序辅助计算:

最终得到12条直线的方程

直线0=直线6 { X=186 }

直线1=直线7 { 125x+74y=43452 }

直线2=直线8 { -70x-132y=-49056 }

直线3=直线9 { Y=273 }

直线4=直线10 { 70x-132y=-23016 }

直线5=直线11 { 121x-74y=2304 }

上面说了每个区域由两条直线和一个弧线组成,且它们的方程已经求解出来了,接下来只需要组合成每个时间段的约束方程组即可(特别要注意的是,与平面坐标系不同,屏幕坐标y值越往下越大):

0~1 { x>186 ; 125x+74y<43452 ; (x-186)²+(y-273)²≤143² }

1~2 { 125x+74y>43452 ; -70x-132y>-49056 ; (x-186)²+(y-273)²≤143² }

2~3 { -70x-132y<-49056 ; y<273 ; (x-186)²+(y-273)²≤143² }

3~4 { y>273 ; 70x-132y>-23016 ; (x-186)²+(y-273)²≤143² }

4~5 { 70x-132y<-23016 ; 121x-74y>2304 ; (x-186)²+(y-273)²≤143² }

5~6 { 121x-74y<2304 ; x>186 ; (x-186)²+(y-273)²≤143² }

6~7 { x<186 ; 125x+74y>43452 ; (x-186)²+(y-273)²≤143² }

7~8 { 125x+74y<43452 ; -70x-132y<-49056 ; (x-186)²+(y-273)²≤143² }

8~9 { -70x-132y>-49056 ; y>273 ; (x-186)²+(y-273)²≤143² }

9~10 { y<273 ; 70x-132y<-23016 ; (x-186)²+(y-273)²≤143² }

10~11 { 70x-132y>-23016 ; 121x-74y<2304 ; (x-186)²+(y-273)²≤143² }

11~0 { 121x-74y>2304 ; x<186 ; (x-186)²+(y-273)²≤143² }

最后把获取到的点击坐标,带入到约束方程组中,就可以知道用户点击的是哪个区域,完成效果如下图所示:

三、明天的计划

为时钟的各个时间区域增加点击功能,使它受到点击后由灰色变为绿色

四、附录代码部分,给感兴趣的同学参考:

判断点击区域的代码:

<template>
	<view @click="getPosition">
		<image src="../../img/clock/clock.png"></image>
	</view>
</template>

<script>
	export default {
		methods: {
			getPosition(event){
				var x = event.touches[0].clientX
				var y = event.touches[0].clientY
				// console.log(x,y)
				if(x>186 && 125*x+74*y<43452 && (x-186)*(x-186)+(y-273)*(y-273)<143*143){
					console.log("位于0~1时段!")
				}else if(125*x+74*y>43452 && -70*x-132*y>-49056 && (x-186)*(x-186)+(y-273)*(y-273)<143*143){
					console.log("位于1~2时段!")
				}else if(-70*x-132*y<-49056 && y<273 && (x-186)*(x-186)+(y-273)*(y-273)<143*143){
					console.log("位于2~3时段!")
				}else if(y>273 && 70*x-132*y>-23016 && (x-186)*(x-186)+(y-273)*(y-273)<143*143){
					console.log("位于3~4时段!")
				}else if(70*x-132*y<-23016 && 121*x-74*y>2304 && (x-186)*(x-186)+(y-273)*(y-273)<143*143){
					console.log("位于4~5时段!")
				}else if(121*x-74*y<2304 && x>186 && (x-186)*(x-186)+(y-273)*(y-273)<143*143){
					console.log("位于5~6时段!")
				}else if(x<186 && 125*x+74*y>43452 && (x-186)*(x-186)+(y-273)*(y-273)<143*143){
					console.log("位于6~7时段!")
				}else if(125*x+74*y<43452 && -70*x-132*y<-49056 && (x-186)*(x-186)+(y-273)*(y-273)<143*143){
					console.log("位于7~8时段!")
				}else if(-70*x-132*y>-49056 && y>273 && (x-186)*(x-186)+(y-273)*(y-273)<143*143){
					console.log("位于8~9时段!")
				}else if(y<273 && 70*x-132*y<-23016 && (x-186)*(x-186)+(y-273)*(y-273)<143*143){
					console.log("位于9~10时段!")
				}else if(70*x-132*y>-23016 && 121*x-74*y<2304 && (x-186)*(x-186)+(y-273)*(y-273)<143*143){
					console.log("位于10~11时段!")
				}else if(121*x-74*y>2304 && x<186 && (x-186)*(x-186)+(y-273)*(y-273)<143*143){
					console.log("位于11~0时段!")
				}			
			}
		}
	}
</script>

Java获取直线两个点,求直线方程的代码:

import java.util.Scanner;

//输入两个点的坐标,计算对应直线方程
public class Math_equationOf_StraightLine {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		
		//获取A坐标
		System.out.println("输入A点坐标:");
		String A = scan.nextLine();
		String[] array_A = A.split(",");
		int A_x = Integer.parseInt(array_A[0]);
		int A_y = Integer.parseInt(array_A[1]);
		
		//获取B坐标
		System.out.println("输入B点坐标:");
		String B = scan.nextLine();
		String[] array_B = B.split(",");
		int B_x = Integer.parseInt(array_B[0]);
		int B_y = Integer.parseInt(array_B[1]);
		
		//计算
		int coefficient_x = A_y-B_y; // x系数
		int coefficient_y = B_x-A_x; // y系数
		int const_number = (B_x*A_y)-(A_x*B_y); // 常数项
		
                //输出
		if(coefficient_y>0) {
			System.out.println("直线方程为:"+coefficient_x+"x+"+coefficient_y+"y="+const_number);
		}else if(coefficient_y<0) {
			System.out.println("直线方程为:"+coefficient_x+"x"+coefficient_y+"y="+const_number);
		}else {
			System.out.println("直线方程为:"+coefficient_x+"x="+const_number);
		}
	}
}