1. можно соориентироваться по сумме всех внешних и внутренних углов
2. для соосных отрезков (не считается биссектриса в такой схеме)) просто брать перпендикуляр
Код AS3:
package
{
import flash.display.Graphics;
import flash.display.Sprite;
import flash.geom.Point;
public class Main extends Sprite
{
public function Main():void
{
var a:Point = new Point(100, 200);
var b:Point = new Point(200, 100);
var c:Point = new Point(400, 200);
var d:Point = new Point(250, 310);
var e:Point = new Point(200, 300);
var f:Point = new Point(150, 290);
var points:Array = [a, b, c, d, e, f];
// другое направление обхода
//var points:Array = [f, e, d, c, b, a];
graphics.lineStyle(0);
drawPoly(graphics, points);
graphics.lineStyle(0, 0xFF0000);
var offsetPoints:Array = calcOffsetPoints(points, 20);
drawPoly(graphics, offsetPoints);
}
public static function calcOffsetPoints(points:Array, distance:Number = 0):Array
{
var res:Array = [];
var len:int = points.length;
// нправление обхода
var angle1:Number = 0;
var angle2:Number = 0;
for (var j:int = 0; j < len; j++)
{
var dp1:Point = points[(j + 1) % len].subtract(points[(j + 0) % len]);
var dp2:Point = points[(j + 1) % len].subtract(points[(j + 2) % len]);
var a1:Number = Math.atan2(dp1.y, dp1.x);
var a2:Number = Math.atan2(dp2.y, dp2.x);
var da1:Number = a1 - a2;
var da2:Number = a2 - a1;
if (da1 < 0)
da1 += Math.PI * 2;
if (da2 < 0)
da2 += Math.PI * 2;
angle1 += da1;
angle2 += da2;
}
var winding:Boolean = angle2 - angle1 > 0;
// расчет точек
for (var i:int = 0; i < len; i++)
{
var p0:Point = points[i];
var p1:Point = points[(i + 1) % len];
var p2:Point = points[(i + 2) % len];
var norm1:Point = p0.subtract(p1);
var norm2:Point = p2.subtract(p1);
norm1.normalize(1);
norm2.normalize(1);
var bisectrix:Point = norm1.add(norm2);
// соосность отрезков
if (bisectrix.length == 0)
{
bisectrix.y = norm1.x;
bisectrix.x = norm1.y;
}
var normRatio:Number = distance / (bisectrix.x * norm1.y - bisectrix.y * norm1.x);
bisectrix.x *= normRatio;
bisectrix.y *= normRatio;
// учитываем направление обхода
var offsetPoint:Point = winding ? p1.subtract(bisectrix) : p1.add(bisectrix);
res.push(offsetPoint);
}
return (res);
}
public static function drawPoly(graphics:Graphics, points:Array):void
{
graphics.moveTo(points[points.length - 1].x, points[points.length - 1].y);
for (var i:int = 0; i < points.length; i++)
{
graphics.lineTo(points[i].x, points[i].y);
}
}
}
}