- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我想让 SKSpriteNodes 沿着字母轮廓移动。我有很多封信,但这里有一个例子:
我希望 Sprite 沿着红线移动。我发现这个答案主要涵盖了我的问题:Get path to trace out a character in an iOS UIFont
答案来自这个良好且有效的示例代码:
let font = UIFont(name: "HelveticaNeue", size: 64)!
var unichars = [UniChar]("P".utf16)
var glyphs = [CGGlyph](count: unichars.count, repeatedValue: 0)
let gotGlyphs = CTFontGetGlyphsForCharacters(font, &unichars, &glyphs, unichars.count)
if gotGlyphs {
let cgpath = CTFontCreatePathForGlyph(font, glyphs[0], nil)!
let path = UIBezierPath(CGPath: cgpath)
print(path)
XCPlaygroundPage.currentPage.captureValue(path, withIdentifier: "glyph \(glyphs[0])")
}
但是我仍然遇到了一个问题,因为我的 Sprite 没有为所有字母完成围绕字母的完整路径,而是例如用“P”停在这里(并从底部开始):
我尝试在 path
中添加一些点像这样:
CGPathAddLineToPoint(path, nil, 0, 0)
但结果不起作用可能是因为添加的点在 <Close>
之后声明:
<UIBezierPath: 0x7889ff70; <MoveTo {25.950001, 55.800003}>,
<LineTo {25.950001, 95.100006}>,
<LineTo {53.850002, 95.100006}>,
<QuadCurveTo {71.625, 90.075005} - {66, 95.100006}>,
<QuadCurveTo {77.25, 75.450005} - {77.25, 85.050003}>,
<QuadCurveTo {71.625, 60.750004} - {77.25, 65.850006}>,
<QuadCurveTo {53.850002, 55.800003} - {66, 55.650002}>,
<Close>,
<MoveTo {11.700001, 107.10001}>,
<LineTo {11.700001, 0}>,
<LineTo {25.950001, 0}>,
<LineTo {25.950001, 43.800003}>,
<LineTo {58.650002, 43.800003}>,
<QuadCurveTo {83.175003, 52.050003} - {74.850006, 43.650002}>,
<QuadCurveTo {91.5, 75.450005} - {91.5, 60.450001}>,
<QuadCurveTo {83.175003, 98.775002} - {91.5, 90.450005}>,
<QuadCurveTo {58.650002, 107.10001} - {74.850006, 107.10001}>,
<Close>,
<LineTo {0, 0}>
最佳答案
首先,您需要一个方法来检索 CGPath
中的所有元素.
我已将此 method 翻译成 Swift (您还找到了如何使用它的示例)。
正如我在您的代码中看到的那样,您还需要知道组成路径的元素种类,但是 CGPathElement
与 UnsafeMutablePointer<CGPoint>
一起工作(这可能不太舒服),因此您可以通过创建一个具有两个输出数组的函数来修改我的翻译:
//MARK: - CGPath extensions
extension CGPath {
func getPathElementsPointsAndTypes() -> ([CGPoint],[CGPathElementType]) {
var arrayPoints : [CGPoint]! = [CGPoint]()
var arrayTypes : [CGPathElementType]! = [CGPathElementType]()
self.forEach { element in
switch (element.type) {
case CGPathElementType.MoveToPoint:
arrayPoints.append(element.points[0])
arrayTypes.append(element.type)
case .AddLineToPoint:
arrayPoints.append(element.points[0])
arrayTypes.append(element.type)
case .AddQuadCurveToPoint:
arrayPoints.append(element.points[0])
arrayPoints.append(element.points[1])
arrayTypes.append(element.type)
arrayTypes.append(element.type)
case .AddCurveToPoint:
arrayPoints.append(element.points[0])
arrayPoints.append(element.points[1])
arrayPoints.append(element.points[2])
arrayTypes.append(element.type)
arrayTypes.append(element.type)
arrayTypes.append(element.type)
default: break
}
}
return (arrayPoints,arrayTypes)
}
}
之后你有一个点数组和一个类型的镜面数组,它们解释了我们列表中每个点的类型。这次都是closePath
被删除。
现在是时候根据您的情况重新创建路径:
func createNewPath(path:CGPath) -> UIBezierPath {
let (points,types) = path.getPathElementsPointsAndTypes()
if points.count <= 1 {
return UIBezierPath() // exit
}
let pathRef = UIBezierPath()
var i = 0
while i < points.count {
switch (types[i]) {
case CGPathElementType.MoveToPoint:
pathRef.moveToPoint(CGPointMake(points[i].x,points[i].y))
case .AddLineToPoint:
pathRef.addLineToPoint(CGPointMake(points[i].x,points[i].y))
case .AddQuadCurveToPoint:
pathRef.addQuadCurveToPoint(CGPointMake(points[i].x,points[i].y), controlPoint: CGPointMake(points[i+1].x,points[i+1].y))
i += 1
case .AddCurveToPoint:
pathRef.addCurveToPoint(CGPointMake(points[i].x,points[i].y), controlPoint1: CGPointMake(points[i+1].x,points[i+1].y), controlPoint2: CGPointMake(points[i+2].x,points[i+2].y))
i += 2
default: break
}
i += 1
}
//pathRef.closePath() if you want to add new elements dont uncomment this
return pathRef
}
启动此方法后,所有closePath
都会清理您的路径并准备好根据需要添加新行。
关于ios - Swift:如何向封闭的 CGPath 添加点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37088660/
我在 CAShapeLayer 上执行了一些 CGPath(一个带有两个圆圈的多边形)。 我可以像这样修剪/减去路径吗? 最佳答案 无需计算,可以在绘制时使用 kCGBlendModeClear 获得
我试图将 UITextField 的左上角和左下角四舍五入。这是我正在使用的代码: override func viewDidLayoutSubviews() { super.viewDidL
我有一个代表椭圆的 SKShape 节点。玩家被放置在基于椭圆 CGPath 的贝塞尔路径的当前点上: 我有两个玩家节点可以执行的操作。玩家可以顺时针或逆时针沿着路径行驶。 rotateCounter
我在 CGPath.h 头文件中找到了它。我很好奇这个 const 的作用是什么? typedef struct CGPath *CGMutablePathRef; typedef const str
我正在使用 CGPath 绘制形状并在绘制后添加到 CAShapeLayer。我正在使用 CGPathGetPathBoundingBox() 获取框架(此框架将设置为 CAShapeLayer)但它
下面的代码有点问题。 points 数组是由寻路算法提供的一组点,它给出了在下面的方法中创建的开始和结束 CGPoints 之间的最短路径。调试此代码后,我知道它有效。 我认为是 CGPath 导致了
我已经研究了一段时间了,作为一个初学者,我似乎无法完成它。我想要做的是采用简单的渐变,并用它来描边 CGPath。我尝试使用 CGContextSetStokePattern 和 PNG 线的宽度和一
我有一个 UIView,其中包含一个带有不规则大小切片的“饼图”,我需要它们是可点击的区域。通过大量的反复试验,我写了一个方法来制作馅饼,但现在我不知道如何将这些切片分成区域。目前这个方法返回 voi
我想创建一个类别来“扩展”CGPath 的“类别”并添加更多功能。因为 CGPath 不是 ObjectiveC 的常规对象,我该怎么做? 请原谅我对c/c++的了解不足 最佳答案 很简单,您只需编写
我正在使用 Swift 制作游戏,并且我有一个任意角度的 CGPath。现在让我们假设它始终是一条直线。 我想创建的是这样的: 我已经尝试了一种非常简单的方法,即以黑色的粗线宽进行描边,复制路径,然后
是否可以在创建时绘制 CGPath(添加每条线时)而不是立即绘制点的整个路径?我希望看到在添加线条时绘制的路径。 此外,是否可以一次绘制一条线作为较大路径的一部分,而不是每次都在自身上绘制一条额外的线
我正在尝试找到一种方法来创建随机闭合平滑路径(CGPath 或 UIBezierPath)。我读过 De Casteljau's algorithm以及其他关于贝塞尔路径的文章,但它似乎不符合我试图实
简单地说,我正在寻找可在 iOS 上使用的与 NSBezierPath 的 -bezierPathByFlatteningPath 等效的方法。这对我来说是直接处理 CGPath 的函数还是 UIBe
更新 我通过使用 OpenGL 绘制所有内容来绕过 CG 的限制。仍然存在一些问题,但到目前为止,它的工作速度要快得多。 一些有趣的点: GLKView :这是一个特定于 iOS 的 View ,它对
我正在尝试绘制一个 CGPath,它的笔划有一个笔划。 基本上我想使用 CGPath 画一条线。然后我想返回并在最后一个 CGPath 的两侧画线,使其具有轮廓效果。 这条线可以以任何方式弯曲和转动,
如何删除路径的某些部分?我在屏幕上绘制了一条路径,现在假设我想删除 1/3: 我试过这样做(路径是我的原始路径,cPath是将被剪切的副本): let sizePath = CGPathGetBoun
我的新游戏 Sprite 有问题... 我的“汽车”在第一圈完美地沿着赛道行驶,但从那时起,它似乎在每圈结束时都会发生偏移。有人能告诉我我做错了什么吗? - (void)createSceneCont
我需要一些示例代码,我可以在其中为曲线/圆弧路径设置动画,该路径应该绘制一个完整的圆作为动画? 我们将不胜感激。 谢谢,周六 最佳答案 更新:意识到这个问题有更好的解决方案。只需创建一个圆形路径并将
我意识到在 iPhone 上让图像遵循预先确定的路径并不是很困难(请参阅 here ),但我想知道图像是否有可能仅遵循部分的路径。例如,如果我有一条从 A 到 B 的路径,如何使图像仅以动画形式呈现朝
假设我有一个 CGPath,它是 CGContextRef 中的一个圆圈。我想做的是用颜色填充路径的反面。下面演示了其中圆圈是当前绘制的路径,我想用颜色填充圆圈的反面,留下一个空洞: 最佳答案 首先将
我是一名优秀的程序员,十分优秀!