惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Blog — PlanetScale
Blog — PlanetScale
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The Last Watchdog
The Last Watchdog
AI
AI
Recent Announcements
Recent Announcements
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Stack Overflow Blog
Stack Overflow Blog
V
Visual Studio Blog
J
Java Code Geeks
TaoSecurity Blog
TaoSecurity Blog
L
LangChain Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Project Zero
Project Zero
Microsoft Security Blog
Microsoft Security Blog
量子位
T
Threatpost
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园 - Franky
博客园 - 聂微东
L
LINUX DO - 最新话题
Security Archives - TechRepublic
Security Archives - TechRepublic
Hugging Face - Blog
Hugging Face - Blog
T
The Blog of Author Tim Ferriss
P
Proofpoint News Feed
The GitHub Blog
The GitHub Blog
C
Check Point Blog
宝玉的分享
宝玉的分享
G
Google Developers Blog
Spread Privacy
Spread Privacy
Cloudbric
Cloudbric
SecWiki News
SecWiki News
有赞技术团队
有赞技术团队
www.infosecurity-magazine.com
www.infosecurity-magazine.com
W
WeLiveSecurity
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
美团技术团队
V
Vulnerabilities – Threatpost
Cyberwarzone
Cyberwarzone
A
Arctic Wolf
P
Privacy & Cybersecurity Law Blog
P
Palo Alto Networks Blog
H
Help Net Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Cisco Talos Blog
Cisco Talos Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
A
About on SuperTechFans
N
Netflix TechBlog - Medium
罗磊的独立博客
月光博客
月光博客

博客园 - kingBook

git patch git 修改最后一次提交的日期 Win10 修改特定格式文件的右键快捷菜单 TypeScript async、 await、Promise LayaAir3.x 侦听程序退出 旋转力学例子 旋转力学公式 LayaAir3.x 侦听键盘事件 URP 阴影 TypeScript 里的 override TypeScript 类的自身类型 Unity 二维数组序列化 C# 匿名对象、动态属性 Cocos Creator 安卓模拟器中无法运行 Unity Editor 保存图片、缩放纹理 LayaAir3.2.0-beta.2 设置2d刚体线性速度,在不同设备(分辨率)下,表现不一致的问题 LayaAir3.x 物理2D碰撞事件 TypeScirpt 声明Map类型变量 TypeScript 声明函数类型变量
凹多边形碰撞检测
kingBook · 2025-03-01 · via 博客园 - kingBook
package {
    import flash.display.Sprite;
    import flash.geom.Point;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.events.MouseEvent;
    import flash.events.Event;

    public class ConcaveCollisionExample extends Sprite {
        private var poly1Sprite:Sprite;
        private var poly2Sprite:Sprite;
        private var resultTF:TextField;
        
        // 多边形本地坐标(相对于各自Sprite)
        private var poly1Local:Array = [
            new Point(0, 0),
            new Point(100, 0),
            new Point(100, 100),
            new Point(50, 50),
            new Point(0, 100)
        ];
        
        private var poly2Local:Array = [
            new Point(0, 0),
            new Point(100, 0),
            new Point(100, 100),
            new Point(50, 50),
            new Point(0, 100)
        ];

        public function ConcaveCollisionExample() {
            createPolygons();
            setupInteraction();
            createResultDisplay();
            updateCollision();
        }

        private function createPolygons():void {
            // 创建并绘制红色多边形
            poly1Sprite = new Sprite();
            poly1Sprite.x = 100;
            poly1Sprite.y = 100;
            drawPolygon(poly1Sprite, poly1Local, 0xFF0000);
            addChild(poly1Sprite);

            // 创建并绘制蓝色多边形
            poly2Sprite = new Sprite();
            poly2Sprite.x = 180;
            poly2Sprite.y = 150;
            drawPolygon(poly2Sprite, poly2Local, 0x0000FF);
            addChild(poly2Sprite);
        }

        private function drawPolygon(target:Sprite, points:Array, color:uint):void {
            target.graphics.clear();
            target.graphics.lineStyle(2, 0x000000);
            target.graphics.beginFill(color, 0.5);
            target.graphics.moveTo(points[0].x, points[0].y);
            for (var i:int = 1; i < points.length; i++) {
                target.graphics.lineTo(points[i].x, points[i].y);
            }
            target.graphics.lineTo(points[0].x, points[0].y);
            target.graphics.endFill();
        }

        private function setupInteraction():void {
            // 启用交互
            poly1Sprite.buttonMode = true;
            poly2Sprite.buttonMode = true;
            
            // 添加事件监听
            poly1Sprite.addEventListener(MouseEvent.MOUSE_DOWN, startDragPoly);
            poly2Sprite.addEventListener(MouseEvent.MOUSE_DOWN, startDragPoly);
            stage.addEventListener(MouseEvent.MOUSE_UP, stopDragPoly);
        }

        private function createResultDisplay():void {
            resultTF = new TextField();
            resultTF.defaultTextFormat = new TextFormat("Arial", 20, 0x000000);
            resultTF.x = 50;
            resultTF.y = 300;
            resultTF.width = 300;
            addChild(resultTF);
        }

        private function startDragPoly(e:MouseEvent):void {
            e.target.startDrag();
            addEventListener(Event.ENTER_FRAME, updateCollision);
        }

        private function stopDragPoly(e:MouseEvent):void {
            stopDrag();
            removeEventListener(Event.ENTER_FRAME, updateCollision);
            updateCollision();
        }

        private function updateCollision(e:Event = null):void {
            // 转换本地坐标为全局坐标
            var poly1Global:Array = convertLocalToGlobal(poly1Local, poly1Sprite);
            var poly2Global:Array = convertLocalToGlobal(poly2Local, poly2Sprite);
            
            // 检测碰撞
            var collision:Boolean = checkCollision(poly1Global, poly2Global);
            resultTF.text = "碰撞检测结果: " + collision;
        }

        private function convertLocalToGlobal(localPoints:Array, sprite:Sprite):Array {
            var globalPoints:Array = [];
            for each (var p:Point in localPoints) {
                globalPoints.push(new Point(sprite.x + p.x, sprite.y + p.y));
            }
            return globalPoints;
        }

        // 以下碰撞检测方法保持不变
        private function checkCollision(polyA:Array, polyB:Array):Boolean {
            for (var i:int = 0; i < polyA.length; i++) {
                var a1:Point = polyA[i];
                var a2:Point = polyA[(i + 1) % polyA.length];
                
                for (var j:int = 0; j < polyB.length; j++) {
                    var b1:Point = polyB[j];
                    var b2:Point = polyB[(j + 1) % polyB.length];
                    
                    if (segmentsIntersect(a1, a2, b1, b2)) {
                        return true;
                    }
                }
            }

            for each (var p:Point in polyA) {
                if (isPointInPolygon(p, polyB)) return true;
            }
            
            for each (p in polyB) {
                if (isPointInPolygon(p, polyA)) return true;
            }

            return false;
        }

        private function segmentsIntersect(a1:Point, a2:Point, b1:Point, b2:Point):Boolean {
            var denominator:Number = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);
            if (denominator == 0) return false;

            var ua:Number = ((b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x)) / denominator;
            var ub:Number = ((a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x)) / denominator;

            return ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1;
        }

        private function isPointInPolygon(p:Point, polygon:Array):Boolean {
            var inside:Boolean = false;
            for (var i:int = 0, j:int = polygon.length - 1; i < polygon.length; j = i++) {
                var pi:Point = polygon[i];
                var pj:Point = polygon[j];
                
                if (((pi.y > p.y) != (pj.y > p.y)) &&
                    (p.x < (pj.x - pi.x) * (p.y - pi.y) / (pj.y - pi.y) + pi.x)) {
                    inside = !inside;
                }
            }
            return inside;
        }
    }
}