zoukankan      html  css  js  c++  java
  • 绕点旋转(老问题)

    绕某点旋转学习Matrix的使用,以及MatrixTransformer.rotateAroundExternalPoint方法

    圆点可以移动位置,长方形鼠标拖动,先看MatrixTransformer.rotateAroundExternalPoint的使用

    import fl.motion.MatrixTransformer;
    //-----------------初始化全局变量------------
    var m:Matrix;
    //rotateAroundExternalPoint方法的初始矩阵,在点击时初始化
    var tempY:Number 
    = point.y;//旋转初始起点,以后是上一次终点
    var tempX:Number 
    = point.x;//

    //-----------------旋转中心点的移动控制-------------------
    point.addEventListener(MouseEvent.MOUSE_DOWN,downmove);
    function downmove(e:MouseEvent) {
        e.target.startDrag();
        stage.addEventListener(MouseEvent.MOUSE_UP,up);
    }

    //-------------------当鼠标按在线上时------------------
    line.addEventListener(MouseEvent.MOUSE_DOWN,down);
    function down(e:MouseEvent) {
        tempY 
    = mouseY;//得到旋转起始点
        tempX 
    = mouseX;//
        m 
    = line.transform.matrix;//实例化旋转矩阵,不能放在旋转函数中,否则有偏移
        stage.addEventListener(MouseEvent.MOUSE_MOVE,moving_fun);
    //鼠标移动侦听
        stage.addEventListener(MouseEvent.MOUSE_UP,up);
    //鼠标松开侦听
    }

    //-------------------------当鼠标松开时--------------------------
    function up(e:MouseEvent) {
        point.stopDrag();
        stage.removeEventListener(MouseEvent.MOUSE_MOVE,moving_fun);

    }

    //--------------------------鼠标移动时旋转控制-------------------------------
    function moving_fun(e:Event ):void {
        
    //下面的new_A、old_A实际上是规范刻度,逆时针刻度由0~360,顺时针刻度由0~-360,防止由-180移到180产生
        
    //360的增加值,所以需要判断,由转换后的刻度差再累加,来实现连续的绝对值增加的角度
        var new_A:Number 
    = Math.atan2(mouseY - point.y,mouseX - point.x)* 180 / Math.PI;//;
        var old_A:Number 
    = Math.atan2(tempY - point.y,tempX - point.x)* 180 / Math.PI;// ;
        
    if (new_A * old_A < 0 && mouseX - point.x < 0) {//判断是否跨过180(-180)线,0度线不需判断
            
    if (new_A > old_A) {//由负角到正角
                old_A 
    = Math.min(new_A,old_A) + 360;//把正刻度变负
            } 
    else {//由正角到负角
                new_A 
    = Math.min(new_A,old_A) + 360;//把负刻度变正
            }
        }
        
    //把  (new_A-old_A)+  累加,可以得到从x轴开始的逆时针刻度由0~360,顺时针刻度由0~-360的变化值
        
    //MatrixTransformer.rotateAroundInternalPoint(m,e.currentTarget.mouseX,e.currentTarget.mouseY,1);
        MatrixTransformer.rotateAroundExternalPoint(m,point.x,point.y,new_A
    -old_A);//
        line.transform.matrix 
    = m;
        tempY 
    = mouseY;//下一次的起点
        tempX 
    = mouseX;

    }

    再看使用Matrix的使用

    import fl.motion.MatrixTransformer;
    //-----------------初始化全局变量------------
    var m:Matrix;
    //rotateAroundExternalPoint方法的初始矩阵,在点击时初始化
    var tempY:Number 
    = point.y;//旋转初始起点,以后是上一次终点
    var tempX:Number 
    = point.x;//

    //-----------------旋转中心点的移动控制-------------------
    point.addEventListener(MouseEvent.MOUSE_DOWN,downmove);
    function downmove(e:MouseEvent) {
        e.target.startDrag();
        stage.addEventListener(MouseEvent.MOUSE_UP,up);
    }

    //-------------------当鼠标按在线上时------------------
    line.addEventListener(MouseEvent.MOUSE_DOWN,down);
    function down(e:MouseEvent) {
        tempY 
    = mouseY;//得到旋转起始点
        tempX 
    = mouseX;//
        m 
    = line.transform.matrix.clone();//实例化旋转矩阵,不能放在旋转函数中,否则有偏移
        stage.addEventListener(MouseEvent.MOUSE_MOVE,moving_fun);
    //鼠标移动侦听
        stage.addEventListener(MouseEvent.MOUSE_UP,up);
    //鼠标松开侦听
    }

    //-------------------------当鼠标松开时--------------------------
    function up(e:MouseEvent) {
        point.stopDrag();
        stage.removeEventListener(MouseEvent.MOUSE_MOVE,moving_fun);

    }

    //--------------------------鼠标移动时旋转控制-------------------------------
    function moving_fun(e:Event ):void {
        
    //下面的new_A、old_A实际上是规范刻度,逆时针刻度由0~360,顺时针刻度由0~-360,防止由-180移到180产生
        
    //360的增加值,所以需要判断,由转换后的刻度差再累加,来实现连续的绝对值增加的角度
        var new_A:Number 
    = Math.atan2(mouseY - point.y,mouseX - point.x) * 180 / Math.PI;//这里需要角度的大小比较
        var old_A:Number 
    = Math.atan2(tempY - point.y,tempX - point.x) * 180 / Math.PI;//不能换成弧度
        
    if (new_A * old_A < 0 && mouseX - point.x < 0) {//判断是否跨过180(-180)线,0度线不需判断
            
    if (new_A > old_A) {//由负角到正角
                old_A 
    = Math.min(new_A,old_A) + 360;//把正刻度变负
            } 
    else {//由正角到负角
                new_A 
    = Math.min(new_A,old_A) + 360;//把负刻度变正
            }
        }
        
    //把  (new_A-old_A)+  累加,可以得到从x轴开始的逆时针刻度由0~360,顺时针刻度由0~-360的变化值
        m.translate(
    -point.x,-point.y);
        m.rotate((new_A
    -old_A)* Math.PI /180) ;
        
    //上面的new_A、old_A是基于角度的计算和判断,所以弧度要到这里才能转换
        m.translate(point.x,point.y);
        line.transform.matrix 
    = m;
        tempY 
    = mouseY;//下一次的起点
        tempX 
    = mouseX;

    }

    还有一个小实例

    源码如下:

    /*在flash cs3中(cs4适用),当主时间轴(stage)上有影片剪辑的实例,且该影片剪辑有实例名称,
      并且关闭了“自动声明舞台上的实例”功能时(文件
    ->发布设置->flash->ActionScript 3.0设置),
      你需要在文档类中声明类为dynamic,或者打开“自动声明舞台上的实例”
    */
    package {
        
    //作者Joel,修改了时间长后漂移旋转中心的现象
        import fl.motion.MatrixTransformer;
        import flash.display.MovieClip;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.MouseEvent;
        import flash.geom.Matrix;

        
    public class rotateAroundPoint extends Sprite {//dynamic
            
    private var xshift:Number;//x方向偏移旋转中心的位移
            
    private var yshift:Number;//y方向偏移旋转中心的位移
            
    private var isMoving:Boolean;
            
    private var rotation_mc:MovieClip;//选定的旋转目标
            
    private var matrix:Matrix;//旋转目标的矩阵
            
    private var obj:Object;//存储鼠标的位置
            
    private var angularVel:Number;//矩阵旋转的角度
            
    private var decay:Number;//衰减率

            
    public function rotateAroundPoint() {
                init();
            }

            
    private function init():void {
                addEventListener(MouseEvent.MOUSE_DOWN,pressed);
                stage.addEventListener(MouseEvent.MOUSE_UP,released);
                stage.addEventListener(Event.ENTER_FRAME,run);
                isMoving 
    = false;
                decay 
    = .99;
                xshift 
    = 0;
                yshift 
    = 0;
            }
            
    private function pressed(e:Event):void {
                isMoving 
    = true;
                rotation_mc 
    = MovieClip(e.target);
                angularVel 
    = 0;
                xshift 
    = mouseX - rotation_mc.x;
                yshift 
    = mouseY - rotation_mc.y;
                matrix 
    = rotation_mc.transform.matrix;
                obj 
    = {x:mouseX,y:mouseY};

            }

            
    private function released(e:Event):void {
                isMoving 
    = false;
            }

            
    private function run(e:Event):void {
                
    if (isMoving) {
                    
    //当鼠标移动时更新旋转对象的位置,鼠标不动时不影响
                    rotation_mc.x 
    = mouseX - xshift;
                    rotation_mc.y 
    = mouseY - yshift;
                    
                    
    //计算旋转的角度
                    angularVel 
    = angularVel * decay;
                    var A:Number 
    = 0.75;//最大振幅
                    var angle:Number 
    = Math.atan2(rotation_mc.y - mouseY,rotation_mc.x - mouseX);//返回-π~+π
                    angularVel 
    += A * Math.cos(angle);
                    
                    
    //如果鼠标不移动,旋转对象就不需要从本身读取矩阵
                    obj.x!
    =mouseX||obj.y!=mouseY?matrix=rotation_mc.transform.matrix:NaN;
                    MatrixTransformer.rotateAroundExternalPoint(matrix,mouseX,mouseY,angularVel);
                    rotation_mc.transform.matrix
    =matrix;
                    
                    
    //应用矩阵旋转对象时,更新x、y方向的位移
                    xshift
    =mouseX-rotation_mc.x;
                    yshift
    =mouseY-rotation_mc.y;
                    
                    
    //便于鼠标移动时记录下位置
                    obj
    ={x:mouseX,y:mouseY};
                }
            }

        }
    }
     1 import flash.display.MovieClip;
     2 import flash.geom.Matrix;
     3 import flash.geom.Point;
     4 import flash.events.MouseEvent;
     5 import flash.events.Event;
     6 
     7 var isLoop:Boolean = false;
     8 //防止误差累计,在循环外获取一次matrix
     9 var m:Matrix = mc.transform.matrix;
    10 //x、y是mc本地坐标空间的数值
    11 function rotate( x:Number, y:Number, angleDegrees:Number):void
    12 {
    13     var point:Point = new Point(x,y);
    14     //把 point转换到 m 的坐标空间
    15     point = m.transformPoint(point);
    16     //把 m 的坐标空间换成本地坐标空间
    17     m.tx -=  point.x;
    18     m.ty -=  point.y;
    19     //把 m 的坐标空间换成本地坐标空间
    20     m.rotate(angleDegrees*(Math.PI/180));
    21     //把 m 的坐标空间又换回父坐标空间;
    22     m.tx +=  point.x;
    23     m.ty +=  point.y;
    24 
    25     mc.transform.matrix = m;
    26 
    27 }
    28 
    29 this.addEventListener(Event.ENTER_FRAME,init);
    30 function init(e:Event):void
    31 {
    32     if(mc.rotation>=90)
    33     {
    34         mc.rotation=90;
    35         this.removeEventListener(Event.ENTER_FRAME,init);
    36         cl(null)
    37         return;;
    38     }
    39     rotate(0,0,1);
    40 }
    41 stage.addEventListener(MouseEvent.CLICK,cl);
    42 function cl(e:Event):void
    43 {
    44     isLoop = ! isLoop;
    45     if (isLoop)
    46     {
    47         this.addEventListener(Event.ENTER_FRAME,loop);
    48     }
    49     else
    50     {
    51         if (this.hasEventListener(Event.ENTER_FRAME))
    52         {
    53             this.removeEventListener(Event.ENTER_FRAME,loop);
    54         }
    55     }
    56 }
    57 function loop(e:Event):void
    58 {
    59     rotate(100,50,5);
    60 }
  • 相关阅读:
    ubuntu12.04 死机 卡屏 画面冻结解决方案
    Install Firefox 20 in Ubuntu 13.04, Ubuntu 12.10, Ubuntu 12.04, Linux Mint 14 and Linux Mint 13 by PPA
    ListView1.SelectedItems.Clear()
    android studio 下载地址
    jquery.slider.js jquery幻灯片测试
    jquery.hovermenu.js
    jquery.tab.js选项卡效果
    适配 placeholder,jquery版
    jquery.autoscroll.js jquery自动滚动效果
    将 Google Earth 地图集成到自己的窗体上的 简单控件
  • 原文地址:https://www.cnblogs.com/ddw1997/p/1578612.html
Copyright © 2011-2022 走看看