• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Position sprite on edge of polygon

Engaged ,
Dec 02, 2016 Dec 02, 2016

Copy link to clipboard

Copied

Hi all

So, mathematics. This one is to tuff for me. I use this Class: http://snipplr.com/view/67582/as3-drawing-shapes-arc-burst-dashedline-gear-polygon-star-wedge-line/

To draw a polygon. I then want to position a sprite on the edge of that polygon. I would like to define the place on the polygon as a degree, so that 0 and 360 would give me the same result.

I have this script.

package

{

    import flash.display.MovieClip;

    import flash.display.Graphics;

    import flash.display.Sprite;

   

    public class Polygon extends MovieClip

    {

        private var marker:Sprite;

       

        public function Polygon()

        {

            marker = new Sprite();

            addChild(marker);

           

            marker.graphics.beginFill(0xFF0000, .8);

            marker.graphics.drawCircle(0, 0, 10);

           

            graphics.lineStyle(3, 0x0074B9);

           

            positionInPolygon(marker, 400, 300, 5, 200, 0, 20);

           

            DrawingShapes.drawPolygon(graphics, 400, 300, 5, 200, 0);

        }

       

        public static function positionInPolygon(target:Sprite, x:Number, y:Number, sides:uint, radius:Number, angle:Number, atAngle:Number):void

        {

            if (sides <= 2)

            {

                throw ArgumentError("DrawingShapes.drawPolygon() - parameter 'sides' needs to be atleast 3");

                return;

            }

            if (sides > 2)

            {

                var step:Number, start:Number, n:Number, dx:Number, dy:Number;

               

                step = (Math.PI * 2) / sides;

               

                start = (angle / 180) * Math.PI;

               

                // Here I can set an integer instead of zero to jump between corners, not what I want though

                target.x = x+Math.cos(start + (step * 0)) * radius;

                target.y = y+Math.sin(start + (step * 0)) * radius;

            }

        }

    }

}

I need to set target x and y differently. But how?

Let me know if it didn't make sense. I would be graceful for any help.

Thanks,

Jakob Wagner

TOPICS
ActionScript

Views

395

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Engaged , Dec 05, 2016 Dec 05, 2016

Thank you for taking the time. Unfortunately, they need to be distributed evenly. I have been trying different things over the weekend and ended up with this, taking a radical different approach. It works. Have the feeling a maths expert could do it in a simpler way, though. And it would be cool if I could bevel the corners, which is going to be impossible with this approach.

Not to worry, this will do for now.

Thanks,

Jakob

package

{

    import flash.display.MovieClip;

    import flash.display.Graphic

...

Votes

Translate

Translate
Community Expert ,
Dec 02, 2016 Dec 02, 2016

Copy link to clipboard

Copied

we need to see DrawingShapes.drawPolygon

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Dec 02, 2016 Dec 02, 2016

Copy link to clipboard

Copied

It's on the link, but I put it below here also.

public static function drawPolygon(target:Graphics, x:Number, y:Number, sides:uint, radius:Number, angle:Number=0):void

        {

            // check that sides is sufficient to build

            if (sides <= 2)

            {

                throw ArgumentError("DrawingShapes.drawPolygon() - parameter 'sides' needs to be atleast 3");

                return;

            }

            if (sides > 2)

            {

                // init vars

                var step:Number, start:Number, n:Number, dx:Number, dy:Number;

                // calculate span of sides

                step = (Math.PI * 2) / sides;

                // calculate starting angle in radians

                start = (angle / 180) * Math.PI;

                target.moveTo(x + (Math.cos(start) * radius), y - (Math.sin(start) * radius));

                // draw the polygon

                for (n = 1; n <= sides; ++n)

                {

                    dx = x + Math.cos(start + (step * n)) * radius;

                    dy = y - Math.sin(start + (step * n)) * radius;

                    target.lineTo(dx, dy);

                }

            }

        }

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 02, 2016 Dec 02, 2016

Copy link to clipboard

Copied

what's wrong with your marker?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Dec 02, 2016 Dec 02, 2016

Copy link to clipboard

Copied

Right now I can position it on each of the corners. I want a way to position it anywhere on the edge.

What I'm really trying to do is to distribute a given number of markers evenly on the edge.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 02, 2016 Dec 02, 2016

Copy link to clipboard

Copied

// this will distribute your points equally by angle, not by distance, along the perimeter

function positionInPolygon(target: Sprite, x: Number, y: Number, sides: uint, radius: Number, angle: Number, atAngle: Number): void {

    if (sides <= 2) {

        //throw ArgumentError("DrawingShapes.drawPolygon() - parameter 'sides' needs to be atleast 3");

        return;

    }

    if (sides > 2) {

        var step: Number, start: Number, n: Number, dx: Number, dy: Number;

        step = (Math.PI * 2) / sides;

        start = (angle / 180) * Math.PI;

var stepN:Number = findStepF(atAngle,sides)

        var x1:Number = x + Math.cos(start + (step *stepN)) * radius;

        var y1:Number = y - Math.sin(start + (step * stepN)) * radius;

        var x2:Number = x + Math.cos(start + (step * (1+stepN))) * radius;

        var y2:Number = y - Math.sin(start + (step * (1+stepN))) * radius;

        var x3:Number = x;

        var y3:Number = y;

        var x4:Number = x+50*Math.cos(atAngle*Math.PI/180);

        var y4:Number = y-50*Math.sin(atAngle*Math.PI/180);

  var d:Number = (x1-x2)*(y3-y4)-(y1-y2)*(x3-x4);

        target.x = ((x1*y2-y1*x2)*(x3-x4)-(x1-x2)*(x3*y4-y3*x4))/d;

        target.y = ((x1*y2-y1*x2)*(y3-y4)-(y1-y2)*(x3*y4-y3*x4))/d;

    }

}

function findStepF(angle:Number,sides:int):int{

    return Math.floor(sides*angle/360);

}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Dec 05, 2016 Dec 05, 2016

Copy link to clipboard

Copied

LATEST

Thank you for taking the time. Unfortunately, they need to be distributed evenly. I have been trying different things over the weekend and ended up with this, taking a radical different approach. It works. Have the feeling a maths expert could do it in a simpler way, though. And it would be cool if I could bevel the corners, which is going to be impossible with this approach.

Not to worry, this will do for now.

Thanks,

Jakob

package

{

    import flash.display.MovieClip;

    import flash.display.Graphics;

    import flash.display.Sprite;

    import flash.geom.Point;

    import flash.events.Event;

   

    public class Polygon extends MovieClip

    {

        private var numberOfMarkers;

        private var markers:Sprite;

        private var offset:Number;

        private var numberOfSides:int;

        private var polygonAngle:Number;

       

        public function Polygon()

        {

            numberOfMarkers = 50;

            offset = 0;

            numberOfSides = 3;

            polygonAngle = 0;

           

            markers = new Sprite();

            addChild(markers);

           

            for(var i:int=0;i<numberOfMarkers;i++)

            {

                var marker:Sprite = new Sprite();

                markers.addChild(marker);

               

                marker.graphics.beginFill(0xFF0000, .8);

                marker.graphics.drawCircle(0, 0, 7);

               

                positionInPolygon(marker, 400, 300, numberOfSides, 200, polygonAngle, 360/numberOfMarkers*i);

            }

           

            addEventListener(Event.ENTER_FRAME, thisEnterFrame);

        }

       

        private function thisEnterFrame(e:Event)

        {

            offset++;

            polygonAngle--;

           

            for(var i:int=0;i<numberOfMarkers;i++)

            {

                var marker:Sprite = markers.getChildAt(i) as Sprite;

               

                positionInPolygon(marker, 400, 300, numberOfSides, 200, polygonAngle, 360/numberOfMarkers*i+offset);

            }

        }

       

        public function positionInPolygon(target:Sprite, x:Number, y:Number, sides:uint, radius:Number, angle:Number, atAngle:Number):void

        {

            if (sides <= 2)

            {

                throw ArgumentError("DrawingShapes.drawPolygon() - parameter 'sides' needs to be atleast 3");

                return;

            }

            if (sides > 2)

            {

                var points:Array = [];

                var step:Number, start:Number, dx:Number, dy:Number;

                step = (Math.PI * 2) / sides;

                start = (angle / 180) * Math.PI;

                points[0] = new Point(x + (Math.cos(start) * radius), y - (Math.sin(start) * radius));

                for (var i:int=1;i<=sides;++i)

                {

                    dx = x + Math.cos(start + (step * i)) * radius;

                    dy = y - Math.sin(start + (step * i)) * radius;

                    points = new Point(dx, dy);

                }

               

                atAngle = atAngle%360;

                // the length of each side

                var sideLength:Number = 2*radius*Math.sin(Math.PI/sides);

                // the length of all sides combined

                var totalLength:Number = sideLength*sides;

                // distance from point 0 if all sides where put in one long line

                var distanceFromStart:Number = totalLength*atAngle/360;

                // index of the start point

                var startPoint:int = Math.floor(distanceFromStart/sideLength);

                // index of the end point

                var endPoint:int = startPoint==sides-1?0:startPoint+1;

                // distance from the start point

                var distanceFromStartPoint:Number = distanceFromStart-(sideLength*startPoint);

                // difference between the to points on x, creating the side a in a right angled triangle

                var a:Number = points[startPoint].x-points[endPoint].x;

                // difference between the to points on y, creating the side b in a right angled triangle

                var b:Number = points[startPoint].y-points[endPoint].y;

                // the angle A, opposite of side a

                var A:Number = Math.atan(a/b);

                // the new side a based on angle A and distanceFromStartPoint

                var na:Number = Math.sin(A)*distanceFromStartPoint*(b<0?1:-1);

                // the new side b based on angle A and distanceFromStartPoint

                var nb:Number = Math.cos(A)*distanceFromStartPoint*(b<0?1:-1);

               

                target.x = points[startPoint].x+na;

                target.y = points[startPoint].y+nb;

            }

        }

    }

}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines