一、项目进度
今天终于把不规则区域的点击判定给实现了,之前想用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);
}
}
}