• uni-app爬坑之旅_开发一个自己的app_day55_实现不规则区域的点击判定


    一、项目进度

    今天终于把不规则区域的点击判定给实现了,之前想用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);
    		}
    	}
    }
    
  • 相关阅读:
    回溯法之图的着色问题
    回溯法基本思想
    L2-006 树的遍历
    P1540 机器翻译
    P1067 多项式输出
    C++STL之map映照容器
    C++STL之multiset多重集合容器
    C++STL之set集合容器
    C++之string基本字符系列容器
    C++STL之vector向量容器
  • 原文地址:https://www.cnblogs.com/huangch/p/14499063.html
Copyright © 2020-2023  润新知