Как нарисовать два пересекающихся круглых отверстия в графике? - PullRequest
2 голосов
/ 25 октября 2011

Мне нужно нарисовать прямоугольник с двумя круглыми отверстиями внутри.Проблема в перехвате кругов.Я хочу, чтобы они объединились и вырезали из фона, но они, кажется, XORed:

enter image description here enter image description here

Сначала я попробовал drawRect и DrawCircle:

graphics.beginFill(0, 0.5);
graphics.drawRect(0, 0, width, height);
graphics.drawCircle(width/2, height/2, 50);
graphics.drawCircle(width/2-30, height/2-30, 50);
graphics.endFill();

Затем я переключился на drawPath, но тоже не повезло:

graphics.beginFill(0, 0.5);
var c1:Object = getCirclePath(width/2-30, height/2-30, 50);
var c2:Object = getCirclePath(width/2, height/2, 50);

graphics.drawPath(new <int>[
        GraphicsPathCommand.MOVE_TO, GraphicsPathCommand.LINE_TO,
        GraphicsPathCommand.LINE_TO, GraphicsPathCommand.LINE_TO,
        GraphicsPathCommand.LINE_TO],
    new <Number>[0, 0, myCanvas.width, 0, myCanvas.width, myCanvas.height,
        0, myCanvas.height, 0, 0]);

myCanvas.graphics.drawPath(c1.commands, c1.data);
myCanvas.graphics.drawPath(c2.commands, c2.data);

graphics.endFill();

здесь getCirclePath возвращает объект с точками для рисования многоугольника, который выглядит как круг.Также я пробовал разные комбинации GraphicsPathWinding констант, но не повезло.

Какие-нибудь предложения, как нарисовать два пересекающихся круглых отверстия в графике?

Ответы [ 2 ]

3 голосов
/ 25 октября 2011

Если вы хотите нарисовать более одного круга без путей, пересекающих друг друга "XOR", вы должны beginFill(...) и endFill() на фигуры, которые вы рисуете .

Я не проверял, но это было бы моей догадкой, чтобы правильно визуализировать перекрывающиеся фигуры.

- РЕДАКТИРОВАТЬ -

ссылка на демонстрацию: http://bit.ly/vBW1ag

Как насчет использования blendmodes?

Попробуйте настроить вашу сцену так:

  • Контейнер для вашего прямоугольника и окружностей имеет blendMode BlendMode.LAYER;
  • Ваш прямоугольник является дочерним по отношению к контейнеру;
  • Вы создаете круги, которые являются дочерними по отношению к контейнеру над прямоугольником, и делаете их blendMode BlendMode.ERASE;

Как только вы начнете Tweening их, вы получите анимированный эффект.

См. Пример ниже (вы можете добавить его в новый проект, чтобы увидеть его запуск)

package 
{
    import flash.display.BlendMode;
    import flash.display.Graphics;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.utils.getTimer;

    public class Main extends Sprite 
    {
    private var _rect:Shape;
    private var _circles:Array;
    private var _container:Sprite;
    private var _subContainer:Sprite;
    private var _numOfCircles:int = 2;

    public function Main():void 
    {
        if (stage) init();
        else addEventListener(Event.ADDED_TO_STAGE, init);
    }

    private function init(e:Event = null):void 
    {
        removeEventListener(Event.ADDED_TO_STAGE, init);
        // entry point

        createContainers();
        createRect( 256, 256 );
        createCircles( 40 );

        centerSetup();

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

    private function createContainers():void 
    {
        _container =    new Sprite();
        _container.blendMode =  BlendMode.LAYER;

        addChild(_container);

        _subContainer = new Sprite();
        _subContainer.blendMode =   BlendMode.ERASE;
        _container.addChild(_subContainer);
    }

    private function createRect(pWidth:Number, pHeight:Number):void 
    {
        _rect = new Shape();

        var g:Graphics =    _rect.graphics;
        g.beginFill(0, 0.5);
        g.drawRect(0, 0, pWidth, pHeight);
        g.endFill();

        /*
         * The canvas that must have the "hole" punched through
         * MUST appear as the first child in the DisplayList.
         */
        _container.addChildAt( _rect, 0 );
    }


    private function createCircles( pRadius:Number ):void 
    {
        var circle:Shape;
        var g:Graphics;

        _circles =  [];

        for (var n:int = _numOfCircles; --n >= 0; ) {
            circle =    new Shape();
            g =         circle.graphics;
            g.beginFill(0xffffff, 1);
            g.drawCircle(0, 0, pRadius);
            g.endFill();


            _subContainer.addChild( circle );
            _circles.push( circle );
        }
    }


    private function centerSetup():void 
    {
        _container.x =  (stage.stageWidth - _rect.width) * .5;
        _container.y =  (stage.stageHeight - _rect.height) * .5;
    }

    private function onUpdate(e:Event):void 
    {
        var circle:Shape;
        var currentTime:Number =    getTimer() * .001;
        var amplitude:Number =      50;
        var direction:int;

        var halfWidth:int =     _rect.width * .5;
        var halfHeight:int =    _rect.height * .5;

        for (var n:int = _numOfCircles; --n >= 0; ) {
            circle =    _circles[n] as Shape;
            direction = (n % 2) == 0 ? 1 : -1;
            circle.x =  halfWidth + Math.cos(currentTime*direction + n) * amplitude;
            circle.y =  halfHeight + Math.sin(currentTime*direction + n) * amplitude;
        }
    }

}

}
0 голосов
/ 25 октября 2011

Во Flash правило обмотки по умолчанию четное нечетное.

http://help.adobe.com/en_US/as3/dev/WS1EE3740D-F65C-43bf-9B12-74E34D7D1CBE.html

Во втором примере добавьте обмотку в свой drawPath на основе GraphicsPathWinding:

import flash.display.GraphicsPathWinding;

GraphicsPathWinding.NON_ZERO

Итак, это станет:

graphics.drawPath(new <int>[/*...*/], new <Number>[/*...*/], GraphicsPathWinding.NON_ZERO);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...