我正在使用绘图应用程序,与其他绘图应用程序相比,线条质量似乎非常低且呈锯齿状。
或者可能是其他应用正在做一些与我不同的事情。
到目前为止我所做的是使用graphics属性绘制线条。我还收集鼠标移动事件上的鼠标位置,以便稍后分配给路径。总结一下:
MouseDownHandler:
mouseDownPoint.x = event.stageX;
mouseDownPoint.y = event.stageY;
drawCommands.push(GraphicsPathCommand.MOVE_TO);
simplePath = "M " + mouseDownPoint.x + " " + mouseDownPoint.y;
MouseMoveHandler:
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;
MouseUpHandler:
myPath.data = simplePath;
当我绘制时,我更新了一行(它是一个UIComponent,但也可以是一个Shape或Sprite - 任何具有graphics属性的东西)。同时我跟踪simplePath字符串中的鼠标位置。
当鼠标启动时,我清除线条图形并显示路径图形元素。路径对此并不重要,但我注意到它看起来比绘制的线稍微干净一些。这可能是因为它有像素提示(它不太清洁)。有时会有文物。并且我包括它以防我出于某种原因需要使用路径。
以下是截图:
像素暗示的版本看起来更加清晰,但它仍然远低于其他应用程序中线条画的质量,在某些情况下,它看起来更加锯齿状。有什么我想念的吗?
注意:我包含了graphics2d和canvas2d,因为我认为这可能与特定语言或平台无关,但可能与绘制图形有关。
答案 0 :(得分:3)
绿线由 Graphics.cubicCurveTo(...)方法生成。最初,您有一个用户提供的点A1,A2,A3 ... An的列表。为了使用三次曲线,你还需要为每个Ak分别绘制2个控制点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 类(适用于笛卡尔坐标和极坐标):https://bitbucket.org/thydmitry/ru.delimiter/src/9083fb46ce1c/classes/ru/delimiter/math/
PS 也许你不需要走极端,用红线就可以了,这是一个简单的 .curveTo(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]);
答案 1 :(得分:0)
有多种原因:
当我有机会时,会尝试在每种情况下发布差异图像。