Java如何对Path2D进行三角剖分?

Mapsy

我正在开发一个应用程序,该应用程序可以从TrueType字体解析字形数据并将其转换为多边形,以便使用OpenGL ES 2.0进行渲染。

我已经成功地字形数据转换成离散的指令,例如MOVE_TOLINE_TOQUAD_TOCLOSE,类似于Java的Path2D类。然后,我对这些路径进行三角剖分以进行渲染。

我遇到的问题是,我似乎以一种非标准的方式处理这些指令,因为我可以有效地渲染某些字体,但是无法渲染其他字体,如下所示。经过一些测试,这似乎是我在LINE_TOBEZIER_TO指令之间移动时使用的决策逻辑,但是我找不到与两种字体都兼容的序列。

是否有任何在线文档可用来对JavaPath2D数据进行三角测量?

1.正确渲染的字形('c')。

正确呈现的字符。

2.来自其他字体('c')的错误显示的字形。

呈现错误的字符。

在下面的代码段中,我正在选择要进行三角剖分的点。无论是在曲线的内部还是外部,都可以绘制Bezier曲线的端点或Bezier控制点。Bezier曲线已正确地与此代码分开渲染。

switch(lVectorPathComponent) {
        case MOVE_TO   :
            /* Append the current vertex to PolygonPoints. */
            if((lLastPathComponent == EVectorPathComponent.BEZIER_TO || lLastPathComponent == EVectorPathComponent.MOVE_TO)) {
                lPolygonPoints.add(new PolygonPoint(pVectorPath.getPathData()[i + 1], pVectorPath.getPathData()[i + 2]));
            }
            /* Initialize the start location of the path. */
            lStartX = pVectorPath.getPathData()[i + 1];
            lStartY = pVectorPath.getPathData()[i + 2];
        break;
        case LINE_TO   : 
            if(lLastPathComponent != EVectorPathComponent.MOVE_TO) {
                lPolygonPoints.add(new PolygonPoint(pVectorPath.getPathData()[i + 1], pVectorPath.getPathData()[i + 2]));
            }
            else {
                if((lNextPathComponent == EVectorPathComponent.LINE_TO || lNextPathComponent == EVectorPathComponent.BEZIER_TO)) {
                    lPolygonPoints.add(new PolygonPoint(pVectorPath.getPathData()[i + 1], pVectorPath.getPathData()[i + 2]));
                }
            }
        break;
        case BEZIER_TO : 
            if(VectorPathGlobal.onCalculateBezierDirection(pVectorPath, i) == pVectorPath.getWindingOrder()) {
                if(!(lLastPathComponent == EVectorPathComponent.LINE_TO && lNextPathComponent == EVectorPathComponent.BEZIER_TO)) {
                    lPolygonPoints.add(new PolygonPoint(pVectorPath.getPathData()[i - 2], pVectorPath.getPathData()[i - 1])); /* Last X, Y */
                    lPolygonPoints.add(new PolygonPoint(pVectorPath.getPathData()[i + 1], pVectorPath.getPathData()[i + 2])); /* Control Point */
                    lPolygonPoints.add(new PolygonPoint(pVectorPath.getPathData()[i + 3], pVectorPath.getPathData()[i + 4])); /* Bezier end X, Y */
                }
            }
            else {
                lPolygonPoints.add(new PolygonPoint(pVectorPath.getPathData()[i + 3], pVectorPath.getPathData()[i + 4]));
            }
        break;
        case CLOSE     : 
            lPolygonPoints.add(new PolygonPoint(lStartX, lStartY));
        break;
    }
}

正确绘制的曲线包含以下命令:

MOVE_TO x:121.0 y:682.0
BEZIER_TO cx:121.0 cy:840.0 x:164.0 y:969.0
BEZIER_TO cx:208.0 cy:1098.0 x:289.0 y:1189.0
BEZIER_TO cx:370.0 cy:1281.0 x:485.0 y:1330.0
BEZIER_TO cx:601.0 cy:1380.0 x:746.0 y:1380.0
BEZIER_TO cx:797.0 cy:1380.0 x:838.0 y:1374.0
BEZIER_TO cx:880.0 cy:1369.0 x:914.0 y:1360.0
BEZIER_TO cx:949.0 cy:1351.0 x:978.0 y:1339.0
BEZIER_TO cx:1007.0 cy:1327.0 x:1033.0 y:1314.0
LINE_TO x:978.0 y:1184.0
BEZIER_TO cx:929.0 cy:1207.0 x:872.0 y:1220.0
BEZIER_TO cx:816.0 cy:1234.0 x:746.0 y:1234.0
BEZIER_TO cx:650.0 cy:1234.0 x:571.0 y:1202.0
BEZIER_TO cx:492.0 cy:1170.0 x:435.0 y:1102.0
BEZIER_TO cx:379.0 cy:1035.0 x:348.0 y:931.0
BEZIER_TO cx:317.0 cy:827.0 x:317.0 y:682.0
BEZIER_TO cx:317.0 cy:537.0 x:349.0 y:432.0
BEZIER_TO cx:382.0 cy:327.0 x:441.0 y:259.0
BEZIER_TO cx:500.0 cy:191.0 x:583.0 y:158.0
BEZIER_TO cx:666.0 cy:126.0 x:768.0 y:126.0
BEZIER_TO cx:811.0 cy:126.0 x:847.0 y:131.0
BEZIER_TO cx:884.0 cy:137.0 x:915.0 y:146.0
BEZIER_TO cx:946.0 cy:155.0 x:972.0 y:165.0
BEZIER_TO cx:998.0 cy:176.0 x:1020.0 y:186.0
LINE_TO x:1062.0 y:58.0
BEZIER_TO cx:1009.0 cy:25.0 x:933.0 y:2.0
BEZIER_TO cx:858.0 cy:-20.0 x:746.0 y:-20.0
BEZIER_TO cx:601.0 cy:-20.0 x:485.0 y:30.0
BEZIER_TO cx:370.0 cy:81.0 x:289.0 y:173.0
BEZIER_TO cx:208.0 cy:265.0 x:164.0 y:394.0
BEZIER_TO cx:121.0 cy:524.0 x:121.0 y:682.0

错误渲染的曲线使用以下内容:

MOVE_TO x:831.0 y:1391.0
BEZIER_TO cx:556.0 cy:1391.0 x:398.0 y:1215.0
BEZIER_TO cx:240.0 cy:1039.0 x:240.0 y:733.0
BEZIER_TO cx:240.0 cy:420.0 x:389.0 y:247.0
BEZIER_TO cx:538.0 cy:74.0 x:815.0 y:74.0
BEZIER_TO cx:999.0 cy:74.0 x:1153.0 y:121.0
LINE_TO x:1153.0 y:31.0
BEZIER_TO cx:1008.0 cy:-20.0 x:791.0 y:-20.0
BEZIER_TO cx:483.0 cy:-20.0 x:306.0 y:179.0
BEZIER_TO cx:129.0 cy:378.0 x:129.0 y:735.0
BEZIER_TO cx:129.0 cy:958.0 x:213.0 y:1128.0
BEZIER_TO cx:298.0 cy:1298.0 x:456.0 y:1390.0
BEZIER_TO cx:615.0 cy:1483.0 x:825.0 y:1483.0
BEZIER_TO cx:1039.0 cy:1483.0 x:1208.0 y:1403.0
LINE_TO x:1167.0 y:1311.0
BEZIER_TO cx:1007.0 cy:1391.0 x:831.0 y:1391.0
Mapsy

我发现LibTess2使用的镶嵌方法与Java的Path2D三角测量兼容。

在我最初的问题中,我遇到的问题是,对于顶点的三角剖分,我使用的是Poly2Tri,它不支持位于多边形边缘的顶点;由于这个问题,正在生成一些似乎逐渐下降到原点的奇怪三角形。LibTess2也难以对非简单多边形进行三角剖分,但是,在检测到冲突的顶点时,它允许用户提供一种通过其combine()方法回调来解决冲突的方法。通过使冲突顶点之间相等,可以解决错误的细分,从而产生正确三角剖分的字形。earcut-j也足够健壮以处理这些顶点。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何从Voronoï图进行三角剖分?

来自分类Dev

用Python在3D中从2D曲面进行点的Delaunay三角剖分?

来自分类Dev

使用Triangle库对凹面进行三角剖分

来自分类Dev

在3D空间中对非平面多边形进行三角剖分

来自分类Dev

在Matlab中对3D对象进行三角剖分

来自分类Dev

OpenCV:如何进行Delaunay三角剖分并返回邻接矩阵?

来自分类Dev

如何对不规则形状的晶格进行三角剖分?

来自分类Dev

三角剖分3D算法

来自分类Dev

三角剖分3D-法线

来自分类Dev

3D 中的 Delaunay 三角剖分

来自分类Dev

Delaunay 三角剖分 - 如何防止扭曲的网格?

来自分类Dev

如何在Python中可视化3D delaunay三角剖分?

来自分类Dev

如何在Python中可视化3D delaunay三角剖分?

来自分类Dev

三角带三角剖分

来自分类Dev

从三角剖分推断

来自分类Dev

射频三角剖分(定位)

来自分类Dev

CGAL三角剖分失败

来自分类Dev

CGAL:CGAL 示例中的 Delaunay 三角剖分与三角剖分

来自分类Dev

CGAL-在3D中进行Delaunay三角剖分后检索到错误的顶点索引

来自分类Dev

用已知边界对平面点集进行三角剖分

来自分类Dev

从坐标集中准确地对中心点进行三角剖分

来自分类Dev

在CGAL中对多面体进行三角剖分

来自分类Dev

用一个孔对多边形进行三角剖分

来自分类Dev

在CGAL中对多面体进行三角剖分

来自分类Dev

周期性3D三角剖分-单元索引

来自分类Dev

在 OpenCV 3 中找不到 OpenCV 2 Delaunay 三角剖分函数

来自分类Dev

运动构造:实现三角剖分

来自分类Dev

在python中带孔的三角剖分

来自分类Dev

libgdx多边形三角剖分