2D向量,求某个向量或是某个点相对另一个向量来说是左边、还是右边

这里写图片描述

/** author: jave.lin, date: 2017-12-05 */
###已知点A(ax,ay),B(bx,by),C(cx,cy),C’(cpx,cpy)
V(A指向B)=简写V(AB)
V(A->B) = B-A=(bx-ax,by-ay)
V(A->C) = C-A=(cx-ax,cy-ay)
V(A->C’) = C’-A=(cpx-ax,cpy-ay)
###使用向量叉乘
如有向量P(px,py),Q(qx,qy)
PxQ=px * qy - py * qx (具体大家去百度:2D向量叉乘,可看看那另一篇BLOG有讲解2D的,3D的3D向量叉乘的理解和记忆)
结果是个标量,叉乘标量结果有个特性:
PxQ<0说明P在Q的逆时针方位
PxQ>0说明P在Q的顺时针方位
PxQ=0说明P、Q共线(同向、反向)

// 伪代码
float value = V(A->B) x V(A->C);
if ( value < 0 )
	printf("向量V(A->B在向量V(A->C)的左边");
else if ( value > 0 )
	printf("向量V(A->B在向量V(A->C)的右边");
else
	printf("向量V(A->B、向量V(A->C)共线");
// 同理以下 V(A->B) x V(A->C')可与同上求法处理
value = V(A->B) x V(A->C')
// 判断value结果即可

###as3 程序演示:

package {

import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.utils.getTimer;

[SWF(width=800, height=600)]
public class Main extends Sprite {
    public function Main()
    {
        stage.frameRate = 60;
        stage.align = StageAlign.TOP_LEFT;
        stage.scaleMode = StageScaleMode.NO_SCALE;
        stage.color = 0x888888;

        _m_pTF = new TextField();
        var f : TextFormat = _m_pTF.defaultTextFormat;
        f.size = 20;
        f.color = 0xffffff;
        _m_pTF.defaultTextFormat = f;
        _m_pTF.setTextFormat( f );
        _m_pTF.autoSize = TextFieldAutoSize.LEFT;
        addChild(_m_pTF);

        _m_pTip = new TextField();
        var f : TextFormat = _m_pTip.defaultTextFormat;
        f.size = 20;
        f.color = 0xffffff;
        _m_pTip.defaultTextFormat = f;
        _m_pTip.setTextFormat( f );
        _m_pTip.autoSize = TextFieldAutoSize.LEFT;
        addChild(_m_pTip);

        stage.addEventListener( Event.ENTER_FRAME, _onEnterFrame );
    }

    private function _onEnterFrame(e : Event ) : void
    {
        var nt : int = getTimer();

        var iet : int = nt - _m_iLT;
        var fet : Number = iet * 1000;

        _updateI( iet );
        _updateF( fet );

        _m_iLT = nt;
    }

    private function _updateI( iDeltaTime : int ) : void
    {
        _m_iFPST += iDeltaTime;
        ++_m_iFPS;
        if ( _m_iFPST >= _m_iFPSInterval )
        {
            _m_iFPST -= _m_iFPSInterval;
            _pushMsg( "FPS:" + _m_iFPS );
            _m_pTF.text = _m_aMsg.join( "\n" );

            _m_aMsg.length = 0;
            _m_iFPS = 0;
        }
    }

    private function _updateF( fDeltaTime : Number ) : void
    {
        var sw : Number = stage.stageWidth;
        var sh : Number = stage.stageHeight;
        var sx : Number = stage.mouseX;
        var sy : Number = stage.mouseY;

        var vx1 : Number, vy1 : Number;
        var vx2 : Number, vy2 : Number;

        graphics.clear();

        graphics.lineStyle( 2, 0x00ff00, 0.5 );
        graphics.moveTo( sw * 0.5, sh * 0.8 );
        graphics.lineTo( sw * 0.5, sh * 0.2 );

        graphics.lineStyle( 2, 0xffff00, 0.5 );
        graphics.moveTo( sw * 0.5, sh * 0.8 );
        graphics.lineTo( sx, sy );

        vx1 = 0; vy1 = sh * 0.2 - sh * 0.8;
        vx2 = sx - sw * 0.5; vy2 = sy - sh * 0.8;

        var v : Number = vx1 * vy2 - vy1 * vx2;
        if ( v > 0 )
        {
            _m_pTip.text = "right";
        }
        else if ( v < 0 )
        {
            _m_pTip.text = "left";
        }
        else
        {
            _m_pTip.text = "same line";
        }

        _m_pTip.x = ( sw - _m_pTip.width ) * 0.5;
        _m_pTip.y = ( sh - _m_pTip.height ) * 0.3;
    }

    private function _pushMsg( msg : String ) : void
    {
        _m_aMsg.push( msg );
    }

    private var _m_iFPS : int;
    private var _m_iFPST : int = 0;
    private var _m_iFPSInterval : int = 1000;
    private var _m_iLT : int;

    private var _m_aMsg : Array = [];

    private var _m_pTF : TextField;

    private var _m_pTip : TextField;
}
}

###运行效果:
这里写图片描述

这里写图片描述

这里写图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值