Actionscript 3 线条质量非常低,边缘参差不齐或模糊

Actionscript 3 线条质量非常低,边缘参差不齐或模糊,actionscript-3,flash,graphics,graphics2d,Actionscript 3,Flash,Graphics,Graphics2d,我正在开发一个绘图应用程序,与其他绘图应用程序相比,线条质量似乎非常低且参差不齐 或者可能是其他应用程序正在做一些与我不同的事情 到目前为止,我所做的是使用graphics属性来绘制线。我还收集鼠标移动事件上的鼠标位置,以便稍后分配给路径。总结如下: MouseDownHandler: mouseDownPoint.x = event.stageX; mouseDownPoint.y = event.stageY; drawCommands.push(GraphicsPathCommand.MO

我正在开发一个绘图应用程序,与其他绘图应用程序相比,线条质量似乎非常低且参差不齐

或者可能是其他应用程序正在做一些与我不同的事情

到目前为止,我所做的是使用graphics属性来绘制线。我还收集鼠标移动事件上的鼠标位置,以便稍后分配给路径。总结如下:

MouseDownHandler:

mouseDownPoint.x = event.stageX;
mouseDownPoint.y = event.stageY;
drawCommands.push(GraphicsPathCommand.MOVE_TO);
simplePath = "M " + mouseDownPoint.x + " " + mouseDownPoint.y;
line.graphics.lineStyle(lineWeight, lineColor, lineAlpha, pixelHinting);
line.graphics.moveTo(previousPoint.x, previousPoint.y);
scaledPoint = new Point(localPoint.x/scaleX, localPoint.y/scaleY);
line.graphics.lineTo(scaledPoint.x, scaledPoint.y);
previousPoint.x = scaledPoint.x;
previousPoint.y = scaledPoint.y;
simplePath += " L " + scaledPoint.x + " " + scaledPoint.y;
MouseMoveHandler:

mouseDownPoint.x = event.stageX;
mouseDownPoint.y = event.stageY;
drawCommands.push(GraphicsPathCommand.MOVE_TO);
simplePath = "M " + mouseDownPoint.x + " " + mouseDownPoint.y;
line.graphics.lineStyle(lineWeight, lineColor, lineAlpha, pixelHinting);
line.graphics.moveTo(previousPoint.x, previousPoint.y);
scaledPoint = new Point(localPoint.x/scaleX, localPoint.y/scaleY);
line.graphics.lineTo(scaledPoint.x, scaledPoint.y);
previousPoint.x = scaledPoint.x;
previousPoint.y = scaledPoint.y;
simplePath += " L " + scaledPoint.x + " " + scaledPoint.y;
穆斯汉德勒:

myPath.data=simplePath

当我绘制时,我会更新线条(这是一个UIComponent,但也可以是一个形状或精灵-任何具有图形属性的东西)。同时,我跟踪simplePath字符串中的鼠标位置

当鼠标向上时,我清除线条图形并显示路径图形元素。路径对此并不重要,但我注意到它看起来比已经绘制的线稍微干净一些。这可能是因为它有像素暗示(它不太干净)。有时会有人工制品。我把它包括在内,以防出于某种原因需要使用路径

以下是屏幕截图:

像素暗示的版本看起来更清晰,但它的质量仍远低于其他应用程序中的线条绘制,在某些情况下,它看起来更参差不齐。有什么我遗漏的吗


注意:我包括了graphics2d和canvas2d,因为我认为这可能与特定的语言或平台无关,但通常可能与绘制图形有关

绿线由Graphics.cubicCurveTo(…)方法生成。最初,您有一个用户提供的A1、A2、A3…An点列表。为了使用三次曲线,您还需要为每个Ak分别绘制两个控制点CFk(向前)和CBk(向后),因此您绘制从A1开始的大曲线,并且从Ak-1到Ak的每个曲线段将采用参数。cubicCurveTo(CFk-1,CBk,Ak)

对于每个Ak(A1和An除外),您可以按以下方式计算CFk和CBk:

(vector)AForward = (vector)(Ak+1 - Ak-1)
(vector)AForward.length = (vector)(Ak+1 - Ak).length / 3

CFk = Ak + (point)AForward

(vector)ABackward = (vector)(Ak-1 - Ak+1)
(vector)ABackward.length = (vector)(Ak-1 - Ak).length / 3

CBk = Ak + (point)ABackward
然后,有A1和An被遗漏了,但我相信你可以自己计算出来

对于向量数学,您可以使用我收集的一些有用的东西中的ru.delimiter.math.Vector2D类(使用笛卡尔坐标和极坐标):

p.S.也许你不需要走那么极端,用红线就可以了,那是一个简单的。曲线(Ak,(Ak+Ak+1)/2)

UPD:一种简单的算法,用于将曲线刻成由点阵列提供的之字形

function middle(A:Point, B:Point):Point
{
    return new Point((A.x + B.x) / 2, (A.y + B.y) / 2);
}

function drawTo(target:Point):void
{
    graphics.lineTo(target.x, target.y);
}

function bendTo(control:Point, target:Point):void
{
    graphics.curveTo(control.x, control.y, target.x, target.y);
}

// This should contain at least 2 points before you start drawing.
var PP:Vector.<Point>;

// Go to the start position.
graphics.lineStyle(0, 0xFF0000);
graphics.moveTo(PP[0].x, PP[0].y);

// Draw a straight line to the center of the first zigzag segment.
drawTo(middle(PP[0], PP[1]));

// For each 3 consequent points A,B and C, connect
// the middle of AB and the middle of BC with a curve.
for (var i:int = 2; i < PP.length; i++)
{
    bendTo(PP[i - 1], middle(PP[i - 1], PP[i]));
}

// Connect the center of the last zigzag segment with the end point.
drawTo(PP[PP.length - 1]);
函数中间(A:点,B:点):点
{
返回新点((A.x+B.x)/2,(A.y+B.y)/2);
}
函数drawTo(目标:点):无效
{
graphics.lineTo(target.x,target.y);
}
函数bendTo(控制:点,目标:点):无效
{
graphics.curveTo(control.x,control.y,target.x,target.y);
}
//在开始绘制之前,该点应至少包含2个点。
向量。;
//转到起始位置。
图形。线条样式(0,0xFF0000);
graphics.moveTo(PP[0].x,PP[0].y);
//在第一个锯齿形线段的中心绘制一条直线。
抽签(中间(PP[0],PP[1]);
//对于每3个后续点A、B和C,连接
//AB的中间和BC的中间有一条曲线。
对于(变量i:int=2;i
绿线由Graphics.cubicCurveTo(…)方法生成。最初,您有一个用户提供的A1、A2、A3…An点列表。为了使用三次曲线,您还需要为每个Ak分别绘制两个控制点CFk(向前)和CBk(向后),因此您绘制从A1开始的大曲线,并且从Ak-1到Ak的每个曲线段将采用参数。cubicCurveTo(CFk-1,CBk,Ak)

对于每个Ak(A1和An除外),您可以按以下方式计算CFk和CBk:

(vector)AForward = (vector)(Ak+1 - Ak-1)
(vector)AForward.length = (vector)(Ak+1 - Ak).length / 3

CFk = Ak + (point)AForward

(vector)ABackward = (vector)(Ak-1 - Ak+1)
(vector)ABackward.length = (vector)(Ak-1 - Ak).length / 3

CBk = Ak + (point)ABackward
然后,有A1和An被遗漏了,但我相信你可以自己计算出来

对于向量数学,您可以使用我收集的一些有用的东西中的ru.delimiter.math.Vector2D类(使用笛卡尔坐标和极坐标):

p.S.也许你不需要走那么极端,用红线就可以了,那是一个简单的。曲线(Ak,(Ak+Ak+1)/2)

UPD:一种简单的算法,用于将曲线刻成由点阵列提供的之字形

function middle(A:Point, B:Point):Point
{
    return new Point((A.x + B.x) / 2, (A.y + B.y) / 2);
}

function drawTo(target:Point):void
{
    graphics.lineTo(target.x, target.y);
}

function bendTo(control:Point, target:Point):void
{
    graphics.curveTo(control.x, control.y, target.x, target.y);
}

// This should contain at least 2 points before you start drawing.
var PP:Vector.<Point>;

// Go to the start position.
graphics.lineStyle(0, 0xFF0000);
graphics.moveTo(PP[0].x, PP[0].y);

// Draw a straight line to the center of the first zigzag segment.
drawTo(middle(PP[0], PP[1]));

// For each 3 consequent points A,B and C, connect
// the middle of AB and the middle of BC with a curve.
for (var i:int = 2; i < PP.length; i++)
{
    bendTo(PP[i - 1], middle(PP[i - 1], PP[i]));
}

// Connect the center of the last zigzag segment with the end point.
drawTo(PP[PP.length - 1]);
函数中间(A:点,B:点):点
{
返回新点((A.x+B.x)/2,(A.y+B.y)/2);
}
函数drawTo(目标:点):无效
{
graphics.lineTo(target.x,target.y);
}
函数bendTo(控制:点,目标:点):无效
{
graphics.curveTo(control.x,control.y,target.x,target.y);
}
//在开始绘制之前,该点应至少包含2个点。
向量。;
//转到起始位置。
图形。线条样式(0,0xFF0000);
graphics.moveTo(PP[0].x,PP[0].y);
//在第一个锯齿形线段的中心绘制一条直线。
抽签(中间(PP[0],PP[1]);
//对于每3个后续点A、B和C,连接
//AB的中间和BC的中间有一条曲线。
对于(变量i:int=2;i
有多种原因:

  • 舞台质量。在Flash Player中,您可以将设置为低、中、高、最佳、8x8、8x8线性、16x16和16x16线性。这会影响线/路径上是否应用了抗锯齿以及应用次数。提高质量有帮助,但在8x8和更高质量的闪存播放器中存在缺陷(非嵌入字体的字体大小减少25%,图形瑕疵,渐变填充颜色计数减少)
  • 像素捕捉。如果你有一条1px的线