Rotation of sprite on polygon edge
Hi
I have these two functions. One positions a number of sprites in a polygon shape, the other the same but in a star. Everything works, except from the last part where I'm rotating the sprites. On some of the edges they are rotated 180 degrees wrong.
So this line in both functions are not correct:
target.rotation = 90-A/(Math.PI/180);
In this example all the triangles should point outwards.
Can anybody figure out why, and tell me how make them all rotate correctly?
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;
private var cornerMarginLeft:Number;
private var cornerMarginRight:Number;
private var sideOffset:Number;
private var startAngle:Number;
private var endAngle:Number;
public function Polygon()
{
numberOfMarkers = 30;
offset = 0;
numberOfSides = 5;
polygonAngle = 0;
cornerMarginLeft = 0;
cornerMarginRight = 0;
sideOffset = 0;
startAngle = 0;
endAngle = 360;
markers = new Sprite();
addChild(markers);
// draw polygon
for(var i:int=0;i<numberOfMarkers;i++)
{
var markerP:Sprite = new Sprite();
markers.addChild(markerP);
markerP.graphics.beginFill(0xFF0000, .8);
markerP.graphics.moveTo(0,-15);
markerP.graphics.lineTo(10,10);
markerP.graphics.lineTo(-10,10);
markerP.graphics.lineTo(0,-15);
positionInPolygon(markerP, 200, 300, numberOfSides, 200, polygonAngle, 360/numberOfMarkers*i+offset, i);
}
// draw star
for(var k:int=0;k<numberOfMarkers;k++)
{
var markerS:Sprite = new Sprite();
markers.addChild(markerS);
markerS.graphics.beginFill(0xFF0000, .8);
markerS.graphics.moveTo(0,-15);
markerS.graphics.lineTo(10,10);
markerS.graphics.lineTo(-10,10);
markerS.graphics.lineTo(0,-15);
positionInStar(markerS, 600, 300, numberOfSides, 100, 200, polygonAngle, 360/numberOfMarkers*k+offset);
}
}
public function positionInStar(target:Sprite, x:Number, y:Number, spikes:uint, innerRadius:Number, outerRadius:Number, angle:Number, atAngle:Number):void
{
if (spikes <= 2)
{
throw ArgumentError("DrawingShapes.drawPolygon() - parameter 'sides' needs to be atleast 3");
return;
}
if (spikes > 2)
{
var points:Array = [];
var step:Number, halfStep:Number, start:Number, n:Number, dx:Number, dy:Number;
step = (Math.PI * 2) / spikes;
halfStep = step / 2;
start = (angle / 180) * Math.PI;
points[0] = new Point(x + (Math.cos(start) * outerRadius), y - (Math.sin(start) * outerRadius));
for (var i:int=1;i<=spikes;++i)
{
dx = x + Math.cos(start + (step * i) - halfStep) * innerRadius;
dy = y - Math.sin(start + (step * i) - halfStep) * innerRadius;
points[(i-1)*2+1] = new Point(dx, dy);
dx = x + Math.cos(start + (step * i)) * outerRadius;
dy = y - Math.sin(start + (step * i)) * outerRadius;
points[(i-1)*2+2] = new Point(dx, dy);
}
atAngle = atAngle%360;
var sideLength:Number = Point.distance(points[0], points[1]);
var cornerMarginLeftLength = sideLength*cornerMarginLeft/100;
var cornerMarginRightLength = sideLength*cornerMarginRight/100;
sideLength -= cornerMarginLeftLength;
sideLength -= cornerMarginRightLength;
var totalLength:Number = sideLength*spikes*2;
var distanceFromStart:Number = totalLength*atAngle/360;
var startPoint:int = Math.floor(distanceFromStart/sideLength);
var endPoint:int = startPoint==spikes*2-1?0:startPoint+1;
var distanceFromStartPoint:Number = distanceFromStart-(sideLength*startPoint)+cornerMarginRightLength+sideOffset;
var a:Number = points[startPoint].x-points[endPoint].x;
var b:Number = points[startPoint].y-points[endPoint].y;
var A:Number = Math.atan(a/b);
var na:Number = Math.sin(A)*distanceFromStartPoint*(b<0?1:-1);
var nb:Number = Math.cos(A)*distanceFromStartPoint*(b<0?1:-1);
target.x = points[startPoint].x+na;
target.y = points[startPoint].y+nb;
target.rotation = 90-A/(Math.PI/180);
}
}
public function positionInPolygon(target:Sprite, x:Number, y:Number, sides:uint, radius:Number, angle:Number, atAngle:Number, index):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);
}
var subEnd = (360-endAngle)*(1-((index+1)/numberOfMarkers));
var subStart = startAngle*((index)/numberOfMarkers);
atAngle = atAngle%360;
atAngle += subEnd;
atAngle -= subStart;
var sideLength:Number = 2*radius*Math.sin(Math.PI/sides);
var cornerMarginLeftLength = sideLength*cornerMarginLeft/100;
var cornerMarginRightLength = sideLength*cornerMarginRight/100;
var totalLength:Number = sideLength*sides;
var distanceFromStart:Number = totalLength*atAngle/360;
var startPoint:int = Math.floor(distanceFromStart/sideLength);
var endPoint:int = startPoint==sides-1?0:startPoint+1;
sideLength -= cornerMarginLeftLength;
sideLength -= cornerMarginRightLength;
totalLength = sideLength*sides;
distanceFromStart = totalLength*atAngle/360;
var distanceFromStartPoint:Number = distanceFromStart-(sideLength*startPoint)+cornerMarginRightLength+sideOffset;
var a:Number = points[startPoint].x-points[endPoint].x;
var b:Number = points[startPoint].y-points[endPoint].y;
var A:Number = Math.atan(a/b);
var na:Number = Math.sin(A)*distanceFromStartPoint*(b<0?1:-1);
var nb:Number = Math.cos(A)*distanceFromStartPoint*(b<0?1:-1);
target.x = points[startPoint].x+na;
target.y = points[startPoint].y+nb;
target.rotation = 90-A/(Math.PI/180);
}
}
}
}