How to rotate BitmapData when using draw method. The task of trimming / cropping in width

I wrote a collision detection class that works using BitmapData.hitTest. Basically, each update, the .draw method is called, and then two BitmapData hitTest'ed against each other to see if there is a collision.

This works very well, however, if I start to rotate the original MovieClip that I use for BitmapData, the transforms are not logged in the draw method. So what I did was go through the Matrix in the drawing method. It works. But here is the actual problem . If I output BitmapData to a bitmap on the scene, I can see that Bitmap is actually rotating, but now it exceeds the boundaries (width and height) of BitmapData. Which crop / crop the image of the original MovieClip.

My first guess would be to rotate BitmapData, but rotation is not possible. There are no properties to help you remove this. Is there another way?

UPDATE . In principle, when a Bitmap MovieClip clone rotates outside the positive coordinate space, it cannot be drawn. It rotates beyond the boundaries of the width and height of BitmapData. I can multiply the borders by 2, and then center the bitmap inside the set borders, but then the start point is never fixed, and the object always moves. It works very well, but makes it impossible to align the object to any specific point.

Here is my isolated test code. This requires that you have a MovieClip on the stage called "iTest". I used a rather vertical arrow shape (above the width), so I could visually track rotations and help emphasize the clipping problem:

var rotateTimer:Timer = new Timer(10);

function rotateObject_init():void
{
 rotateTimer.addEventListener(TimerEvent.TIMER, rotateObject);
 rotateTimer.start();
}

function rotateObject_stop():void
{
 rotateTimer.removeEventListener(TimerEvent.TIMER, rotateObject);
 rotateTimer.stop();
}

function rotateObject(_event:TimerEvent):void
{
 // Deletes the previous bitmap
 if (this.getChildByName("iTestClone") != null)
 {
  removeChild(this.getChildByName("iTestClone"));

  testClone = null;
  testData = null;
 }

 iTest.rotation += 1;

 // Capture source BitmapData
 var testData:BitmapData = new BitmapData(iTest.width, iTest.height, false, 0xFFFFFF); 

 // Capture source transformations
 var testMatrix:Matrix = new Matrix();
 testMatrix.scale(iTest.scaleX, iTest.scaleY);
 testMatrix.rotate( iTest.rotation * (Math.PI / 180) );
 testMatrix.translate(0, 0);

 // Draw source with matrix
 testData.draw(iTest, testMatrix);

 // Output Bitmap
 var testClone:Bitmap = new Bitmap(testData);
 testClone.name = "iTestClone";
 testClone.transform = testMatrix.tra
 addChild(testClone);

 // Always makes sure source is visible
 this.swapChildren(iTest, testClone);
}

rotateObject_init();
+3
3

!

BitmapData , 10 . , . , , , - .

:

bounds

, , BitmapData , x y, .

, ( ):

bounds 2

, , :)

offset

x, , , width, :

var box:Sprite = new Sprite();
box.graphics.lineStyle(0.1);
box.graphics.drawRect(0,0,150,100);
box.rotation = 10;
//get the size of the object rotated
var bounds:Rectangle = box.getBounds(this);
//make a bitmap data
var extra:int = 2;//cheating the trimmed pixels :)
var bitmapData:BitmapData = new BitmapData(bounds.width+extra,bounds.height+extra,false, 0x00009900);
//get the bottom left point
var bl:Point = getBottomLeft(box,bitmapData);
//get the matrix
var m:Matrix = box.transform.matrix;
//offset if
m.tx += Math.abs(bl.x);
//draw, using the offset, rotated matrix
bitmapData.draw(box,m);

var bitmap:Bitmap = new Bitmap(bitmapData);
bitmap.x = bitmap.y = 100;
addChild(bitmap);

function getBottomLeft(displayObject:DisplayObject,data:BitmapData):Point{
    var radius:int = displayObject.getBounds(displayObject).height;
    var angle:Number = displayObject.rotation * Math.PI / 180;
    var angle90:Number = angle + Math.PI * .5;
    return new Point(Math.cos(angle90) * radius, Math.sin(angle90) * radius);
}

BitmapData, . , x, .

:

var box:Sprite = new Sprite();
box.graphics.lineStyle(0.1);
box.graphics.drawRect(0,0,150,100);
box.rotation = 10;

var bounds:Rectangle = box.getBounds(this);
var extra:int = 2;//cheating the trimmed pixels :)
var bitmapData:BitmapData = new BitmapData(bounds.width+extra,bounds.height+extra,false, 0x00009900);

var m:Matrix = box.transform.matrix;
m.tx += Math.abs(getLeftmost(box,bitmapData));
bitmapData.draw(box,m);

var bitmap:Bitmap = new Bitmap(bitmapData);
bitmap.x = bitmap.y = 100;
addChild(bitmap);

function getLeftmost(displayObject:DisplayObject,data:BitmapData):Number{
    var radius:int = displayObject.getBounds(displayObject).height;
    var angle90:Number = displayObject.rotation * Math.PI / 180 + Math.PI * .5;
    return Math.cos(angle90) * radius;
}

:

offset 2

,

: , ^ _ ^

+4

, bitmapData , . , (.. ).

, getBounds(), iTest:

// Capture source BitmapData
var bounds:Rectangle = iTest.getBounds(iTest);
var testData:BitmapData = new BitmapData(bounds.width, bounds.height, false, 0xFFFFFF); 

, , : -)

0

Just use the rotation property:

THENAMEOFMovieClip.rotation=number;

number is the number of degrees you want to rotate.

0
source

Source: https://habr.com/ru/post/1730588/


All Articles