从不规则数量的x,y点制作平滑路径以模拟手写

yiz*_*eel 7 math flash bezier actionscript-3

我试图在AS3(纯粹,而不是Flex)中制作一个模拟手写的"画笔"工具,使笔画变得平滑而不是走投无路.然后,必须将轨迹缩小为可以拖动和变形的三次贝塞尔曲线,从而影响先前绘制的路径(如插图画家的钢笔工具).

我正在跟踪鼠标移动以获得一组点来绘制路径.据我所知,我需要使用这组点进行B样条曲线路径.然后我应该将它减少到三次贝塞尔曲线(在路径中添加'钢笔工具'功能).

我已经开发了钢笔工具,使用的算法可以将Cubic Beziers缩小为Quadratic Beziers(然后使用Flash curveTo函数).但我不知道如何创建B样条(或其他简化),然后将其缩小为贝塞尔曲线.

你知道有什么方法可以做到这一点吗?

Ama*_*osh 7

jhotdraw是在Java中绘制一个开源项目.它将自由手绘图转换为立方贝塞尔曲线.源代码可用 - 下载和翻译.不要害怕项目的大小:你只需要几个类,即:

org.jhotdraw.geom.Bezier
org.jhotdraw.geom.BezierPath
org.jhotdraw.geom.Geom
Run Code Online (Sandbox Code Playgroud)

在翻译时首先将所有集合声明更改为Arrays(如果您仅定位FP10用户,请使用向量).我有一些你可能会觉得在转换中有用的正则表达式 - 如果你愿意,我可以发布它们.


以下是您可能会发现有用的正则表列表.在每对中,将第一个粘贴到搜索文本区域,将第二个粘贴到替换区域,选中正则表达式复选框并使用"查找和替换"按钮.不要使用 Replace All - 这些都不能保证是万无一失的.

替换所有int/double name声明var name:Number

\b(double|int)\s+(\w+)\b

var $2:Number
Run Code Online (Sandbox Code Playgroud)

替换所有Point2D.Double name声明var name:Point

\bPoint2D\.Double\s+(\w+)\b

var $1:Point
Run Code Online (Sandbox Code Playgroud)

int/double name函数签名替换所有声明name:Number

\(([^)]*)\b(?:double|int)\s+(\w+)\b([^)]*?)\)

($1$2:Number$3)
Run Code Online (Sandbox Code Playgroud)

Point2D.Double name函数签名替换所有声明name:Point

\(([^)]*)\b(?:Point2D\.Double)\s+(\w+)\b([^)]*?)\) 

($1$2:Point$3)
Run Code Online (Sandbox Code Playgroud)

在更改方法签名之前,请确保所有方法都是静态的:

(public|private)\s+(?!static)
Run Code Online (Sandbox Code Playgroud)

将方法签名替换为AS格式

(public|private)\s+static\s+(\w+)\s+(\w+)\s*\(([^)]*)\)

$1 static function $3($4):$2
Run Code Online (Sandbox Code Playgroud)

用array [index]替换ArrayList.get(index)//警告:list.get失败(list.size() - 1)

(\w+)\.get\(([^)]+)\)

$1[$2]

//avoid the () failure 

(\w+)\.get\(([^)]*(?:\([^)]*\))[^)]*)\)

$1[$2]
Run Code Online (Sandbox Code Playgroud)

替换ArrayList.set(index, element)array[index] = element //警告:list.set失败(i,list.size())

(\w+)\.set\(([^,]+)\s*,\s*([^)]+)\)

$1[$2] = $3


/*the above regex successfully made the following replacement*/

cleaned.set(cleaned.size() - 1, digitizedPoints[digitizedPoints.size() - 1])

cleaned[cleaned.size() - 1] = digitizedPoints[digitizedPoints.size() - 1]
Run Code Online (Sandbox Code Playgroud)

替换arraylist.add(object)array.push(object)

//would fail if object contains ')'
//add(index, object) should be done with splice

(\w+)\.add\(([^)]+)\)

$1.push($2)

//too many failures - fail safe version - 
//still fails for nested parenthesis  list.add(new Point(a.first(), a.last())) 
//- only three such cases - the effort to match parenthesis wouldn't be worth it
//works for list.add(new Point(3, 4)) - there were many similar cases

(\w+)\.add\(([^)]*(?:\([^)]*\))[^)]*)\)

$1.push($2)
Run Code Online (Sandbox Code Playgroud)

将方法签名替换为AS格式(非静态方法)

(public|private)\s+(?!function)(\w+)\s+(\w+)\s*\(([^)]*)\)

$1 function $3($4):$2
Run Code Online (Sandbox Code Playgroud)

int/double/point/boolean name函数签名替换所有声明name:type

\(([^)]*)\b(\w+)\s+(\w+)\b([^)]*?)\)

($1$3:$2$4)
Run Code Online (Sandbox Code Playgroud)

使用=到AS格式替换其自己行中的所有变量声明

^(\s+)(\w+)\s+(\w+)\s*=\s*(.+?)\s*;(\s*)$

$1var $3:$2 = $4;$5
Run Code Online (Sandbox Code Playgroud)

改变括号的位置.

^(\t)(\s*)([^\n]+)\{\s*(\n)\s+

$1$2$3$4$1$2{$4$1$2
Run Code Online (Sandbox Code Playgroud)

改变} else} \n else

^([ \t]+)}[ \t]*else\b([^\n]*)(\n)

$1}$3$1else$2$3
Run Code Online (Sandbox Code Playgroud)

将一行中的4个变量声明替换为不同行中的AS

^(\t+)(\w+)\s+(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*;[ \t]*(\n)

$1var $3:$2;$7$1var $4:$2;$7$1var $5:$2;$7$1var $6:$2;$7
Run Code Online (Sandbox Code Playgroud)

替换数组声明

^(\s+)\w+\[\]\s*(\w+)\b

$1 var $2:Array
Run Code Online (Sandbox Code Playgroud)

Remove()cast - AS编译器不喜欢它们

(?:\(\w+\)\s*)([^ ,*+;/)><=\-])

$1
Run Code Online (Sandbox Code Playgroud)

将max etc替换为Math.max - AS没有静态导入

(?<!Math\.)\b(max|min|abs|sqrt|PI|cos|sin|atan2)\(

Math.$1(
Run Code Online (Sandbox Code Playgroud)