碰撞算法学习笔记

碰撞算法

圆形与矩形碰撞算法分析

https://blog.csdn.net/arv002/article/details/118501407

2D游戏中的碰撞检测:圆形与矩形碰撞检测

https://www.cnblogs.com/jiangxiaobo/p/5949904.html

点和矩形碰撞

/** 
     *  
     * @param x1 点 
     * @param y1 点 
     * @param x2 矩形view x 
     * @param y2 矩形view y 
     * @param w  矩形view 宽 
     * @param h  矩形view 高 
     * @return 
     */  
    public static boolean isCollision(int x1, int y1, int x2, int y2, int w, int h) {  
        if (x1 >= x2 && x1 <= x2 + w && y1 >= y2 && y1 <= y2 + h) {  
            return true;  
        }   
        return false;  
    }  

矩形碰撞

/** 
     * 检测两个矩形是否碰撞 
     * @return 
     */  
    public boolean isCollisionWithRect(int x1, int y1, int w1, int h1,   
            int x2,int y2, int w2, int h2) {  
        if (x1 >= x2 && x1 >= x2 + w2) {  
            return false;  
        } else if (x1 <= x2 && x1 + w1 <= x2) {  
            return false;  
        } else if (y1 >= y2 && y1 >= y2 + h2) {  
            return false;  
        } else if (y1 <= y2 && y1 + h1 <= y2) {  
            return false;  
        }  
        return true;  
    }  

点(x1,x2) , 圆心(x2,y2) ,半径r

if (Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)) <= r) {  
            // 如果点和圆心距离小于或等于半径则认为发生碰撞  
            return true;  
        }  

圆和圆

/** 
     * 圆形碰撞 
     *  
     * @param x1 
     *            圆形1的圆心X坐标 
     * @param y1 
     *            圆形2的圆心X坐标 
     * @param x2 
     *            圆形1的圆心Y坐标 
     * @param y2 
     *            圆形2的圆心Y坐标 
     * @param r1 
     *            圆形1的半径 
     * @param r2 
     *            圆形2的半径 
     * @return 
     */  
    private boolean isCollisionWithCircle(int x1, int y1, int x2, int y2,  
            int r1, int r2) {  
        // Math.sqrt:开平方  
        // Math.pow(double x, double y): X的Y次方  
        //直角坐标系,依点1和点2做平行线,|x1-x2|为横向直角边,|y1-y2|为纵向直角边 依勾股定理 c^2=a^2+b^2  
        if (Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)) <= r1 + r2) {  
            // 如果两圆的圆心距小于或等于两圆半径和则认为发生碰撞  
            return true;  
        }  
        return false;  
    }  

算法笔记

案例:跟随鼠标碰撞变色

import React, { Component } from 'react';

class App2 extends Component {
    state = {
        list: [
            { x: 200, y: 100, w: 100, h: 100, c: "red" },
            { x: 400, y: 200, w: 100, h: 100, c: "blue" },
        ]

    }

    changeMove = (e) => {
        // 获取状态
        let temp = this.state.list
        // 0跟随鼠标 
        temp[1].x = e.clientX - temp[1].w / 2
        temp[1].y = e.clientY - temp[1].h / 2

        // 方框 碰到 方框 就变色 算法一
        // if (this.box_in_box_way1(temp[0], temp[1])) {
        //     temp[0].c = 'red'
        // } else (temp[0].c = 'blue')

        // 方框 碰到 方框 就变色 算法二
        // if (this.box_in_box_way2(temp[0], temp[1])) {
        //     temp[0].c = 'red'
        // } else (temp[0].c = 'blue')

        // 点是否在圆里
        // let dot = { x: temp[1].x, y: temp[1].y }
        // let circle = {
        //     x: temp[0].x + temp[0].w / 2,
        //     y: temp[0].y + temp[0].w / 2,
        //     r: temp[0].w / 2,
        // }
        // if (this.dot_in_circle(dot, circle)) {
        //     temp[0].c = 'blue'
        // } else (temp[0].c = 'red')

        // 方框 碰撞 园 ---未完成
        if (this.box_in_circle(temp[1], temp[0])) {
            temp[0].c = 'blue'
        } else (temp[0].c = 'red')

        // 更新状态
        this.setState({ list: temp })
    }

    // 方框 是否 碰到 方框 算法一
    box_in_box_way1 = (box1, box) => {
        let dot_1 = { x: box1.x, y: box1.y, }
        let dot_2 = { x: box1.x + box1.w, y: box1.y, }
        let dot_3 = { x: box1.x, y: box1.y + box1.h, }
        let dot_4 = { x: box1.x + box1.w, y: box1.y + box1.h, }
        if (this.dot_in_box(dot_1, box) || this.dot_in_box(dot_2, box) || this.dot_in_box(dot_3, box) || this.dot_in_box(dot_4, box)) {
            return true
        } else {
            return false
        }
    }

    // 方框 是否碰到 方框 算法二
    box_in_box_way2 = (box, obj) => {
        if (obj.x + obj.w < box.x || obj.x > box.x + box.w || obj.y + obj.h < box.y || obj.y > box.y + box.h) {
            return false
        } else {
            return true
        }
    }

    // 点是否在方框里 
    dot_in_box = (dot, box) => {
        if (box.x < dot.x && dot.x < (box.x + box.w) && box.y < dot.y && dot.y < (box.y + box.h)) {
            return true
        } else {
            return false
        }
    }

    // 方框 是否碰到  圆 -----未完成
    box_in_circle = (box, circle) => {
        let temp_circle = {
            x: circle.x + circle.w / 2,
            y: circle.y + circle.w / 2,
            r: circle.w / 2,
        }
        let dot_list = [
            { x: box.x, y: box.y, },
            { x: box.x + box.w, y: box.y, },
            { x: box.x, y: box.y + box.h, },
            { x: box.x + box.w, y: box.y + box.h, },
        ]
        let a = 0
        if (this.box_in_box_way2(box, circle)) {
            for (let i in dot_list) {
                a += this.dot_in_box(dot_list[i], temp_circle)
            }
        }
        return a
    }


    // 点是否在圆里
    dot_in_circle = (dot, circle) => {
        if (Math.sqrt(Math.pow((circle.x - dot.x), 2) + Math.pow((circle.y - dot.y), 2)) < circle.r) {
            return true
        }
        else { return false }
    }

    // 组件加载完成时
    componentDidMount() {
        window.addEventListener('mousemove', this.changeMove)
    }

    // 组件渲染
    render() {
        return (
            <div>
                <div style={{
                    position: 'absolute',
                    left: `${this.state.list[0].x}px`,
                    top: `${this.state.list[0].y}px`,
                    width: `${this.state.list[0].w}px`,
                    height: `${this.state.list[0].h}px`,
                    backgroundColor: this.state.list[0].c,
                    borderRadius: '50%',
                }}></div>

                <div style={{
                    position: 'absolute',
                    left: `${this.state.list[1].x}px`,
                    top: `${this.state.list[1].y}px`,
                    width: `${this.state.list[1].w}px`,
                    height: `${this.state.list[1].h}px`,
                    backgroundColor: this.state.list[1].c,
                }}></div>
            </div>
        );
    }
}

export default App2;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值