- objective-c - iOS 5 : Can you override UIAppearance customisations in specific classes?
- iphone - 如何将 CGFontRef 转换为 UIFont?
- ios - 以编程方式关闭标记的信息窗口 google maps iOS
- ios - Xcode 5 - 尝试验证存档时出现 "No application records were found"
具有以下形状:
我想知道你是如何让它像这样弯曲的:
也类似:
我假设所有的圆/线都打包到一个 CGMutablePath
中,然后对其应用某种曲线、圆弧或四边形曲线,尽管我是甚至难以复制它。有谁知道如何做到这一点?
最佳答案
在您的第一个示例中,您从一个具有多个闭合子路径的路径开始。显然你想扭曲子路径的中心,但让各个子路径相对于它们的(新)中心不扭曲。我将忽略它,因为即使没有它,解决方案也已经非常复杂。
那么,让我们考虑一下如何定义“扭曲场”。我们将使用三个控制点:
warp 保持 fixedPoint 不变。它通过旋转和缩放将起点移动到终点,不是通过简单地插值坐标。
此外,它根据与 fixedPoint 的距离应用旋转和缩放。而不仅仅是基于简单的欧几里得距离。请注意,我们不想对图片中“V”形的顶部端点应用任何旋转或缩放,即使这些端点与 fixedPoint 的距离是可测量的欧氏距离。我们想要测量沿 fixedPoint->startPoint 向量的距离,并随着距离的增加应用更多的旋转/缩放。
这一切都需要一些非常复杂的三角函数。我不会尝试解释细节。我只是要把代码转储给你,作为 UIBezierPath
上的一个类别:
#import <UIKit/UIKit.h>
@interface UIBezierPath (Rob_warp)
- (UIBezierPath *)Rob_warpedWithFixedPoint:(CGPoint)fixedPoint startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint;
@end
请注意,您需要来自 this answer 的 Rob_forEach
类别.
#import "UIBezierPath+Rob_warp.h"
#import "UIBezierPath+Rob_forEach.h"
#import <tgmath.h>
static CGPoint minus(CGPoint a, CGPoint b) {
return CGPointMake(a.x - b.x, a.y - b.y);
}
static CGFloat length(CGPoint vector) {
return hypot(vector.x, vector.y);
}
static CGFloat dotProduct(CGPoint a, CGPoint b) {
return a.x * b.x + a.y * b.y;
}
static CGFloat crossProductMagnitude(CGPoint a, CGPoint b) {
return a.x * b.y - a.y * b.x;
}
@implementation UIBezierPath (Rob_warp)
- (UIBezierPath *)Rob_warpedWithFixedPoint:(CGPoint)fixedPoint startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint {
CGPoint startVector = minus(startPoint, fixedPoint);
CGFloat startLength = length(startVector);
CGPoint endVector = minus(endPoint, fixedPoint);
CGFloat endLength = length(minus(endPoint, fixedPoint));
CGFloat scale = endLength / startLength;
CGFloat dx = dotProduct(startVector, endVector);
CGFloat dy = crossProductMagnitude(startVector, endVector);
CGFloat radians = atan2(dy, dx);
CGPoint (^warp)(CGPoint) = ^(CGPoint input){
CGAffineTransform t = CGAffineTransformMakeTranslation(-fixedPoint.x, -fixedPoint.y);
CGPoint inputVector = minus(input, fixedPoint);
CGFloat factor = dotProduct(inputVector, startVector) / (startLength * startLength);
CGAffineTransform w = CGAffineTransformMakeRotation(radians * factor);
t = CGAffineTransformConcat(t, w);
CGFloat factoredScale = pow(scale, factor);
t = CGAffineTransformConcat(t, CGAffineTransformMakeScale(factoredScale, factoredScale));
// Note: next line is not the same as CGAffineTransformTranslate!
t = CGAffineTransformConcat(t, CGAffineTransformMakeTranslation(fixedPoint.x, fixedPoint.y));
return CGPointApplyAffineTransform(input, t);
};
UIBezierPath *copy = [self.class bezierPath];
[self Rob_forEachMove:^(CGPoint destination) {
[copy moveToPoint:warp(destination)];
} line:^(CGPoint destination) {
[copy addLineToPoint:warp(destination)];
} quad:^(CGPoint control, CGPoint destination) {
[copy addQuadCurveToPoint:warp(destination) controlPoint:warp(control)];
} cubic:^(CGPoint control0, CGPoint control1, CGPoint destination) {
[copy addCurveToPoint:warp(destination) controlPoint1:warp(control0) controlPoint2:warp(control1)];
} close:^{
[copy closePath];
}];
return copy;
}
@end
好的,那么你如何使用这个疯狂的东西呢?对于示例中的“V”这样的路径,您可以这样做:
CGRect rect = path.bounds;
CGPoint fixedPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPoint startPoint = CGPointMake(fixedPoint.x, CGRectGetMaxY(rect));
path = [path Rob_warpedWithFixedPoint:fixedPoint startPoint:startPoint endPoint:endAnchor];
我将 fixedPoint 计算为路径边界框顶部边缘的中心,将 startPoint 计算为底部边缘的中心。 endAnchor
在我的测试程序中受用户控制。在模拟器中看起来像这样:
气泡型路径如下所示:
你可以在这里找到我的测试项目:https://github.com/mayoff/path-warp
关于ios - 如何曲线 CGMutablePath?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25776819/
具有以下形状: 我想知道你是如何让它像这样弯曲的: 也类似: 我假设所有的圆/线都打包到一个 CGMutablePath 中,然后对其应用某种曲线、圆弧或四边形曲线,尽管我是甚至难以复制它。有谁知道如
在以下情况下使用 CGMutablePath 时发生内存泄漏: - (CGMutablePathRef) textMutablePathForFrame:(CGRect)frame { CGA
对于这个项目,我使用 CGMutablePath 的 addCurve 方法在 View 上绘制曲线形状。 我完全不明白的是,如何(或者是否有可能)从可变路径中删除完全相同的曲线?从 API 来看,似
我正在关注 winding rules documentation为 fillRule 属性提供,该属性用于尝试识别某个点是否位于区域内。我的问题是尝试在如下路径中添加多个路径排除项。我试图在 Pla
我有一个应用程序,它允许用户绘制他们自己的地理围栏。现在它的工作方式是用户在屏幕上绘制他们的地理围栏,应用程序跟踪他们正在绘制的位置并将他们的路径存储到 CGMutablePath 中。 我的问题是如
我正在使用 cgmutablepath 绘制一个多边形,我想为多边形填充颜色,但它不起作用,我不知道为什么...... 下面是我的代码: var path = CGMutablePath()
我正在尝试为我的 Xamarin.iOS 应用翻译这段代码: https://github.com/yourtion/YXWaveView/blob/master/YXWaveView/YXWaveV
我使用 CgContext 和 CGMutablePath 来绘制对象,但绘制的图像是相反的。我需要Draw Object到CoreMl绘图分类项目。 我使用触摸事件来绘制对象但是当我向顶部方向绘制时
我已经开始在我的应用程序中添加图表。最初我使用 CGMutablePath() 完成了此操作,但随后将其重构为我们 NSBezierPath()。我发现我应该使用哪个令人困惑,但考虑到 NSBezie
这个问题在这里已经有了答案: Does ARC work with Core Graphics objects? (3 个答案) 关闭 9 年前。
我打算在屏幕上用二维箭头显示 AR 对象的信息。所以我使用 projectPoint 来获取对象在屏幕中的相应位置。我有这个函数来返回将节点的 3D 位置转换为 2D 和 CGPoint 以显示信息文
我有一个简单的椭圆形(由 CGMutablePaths 组成),我希望用户能够从中拖动一个对象。只是想知道这样做有多复杂,我是否需要了解大量的数学和物理知识,或者是否有一些简单的内置方法可以让我做到这
在 Xcode 8 beta 6 中,一些添加路径的函数发生了变化,包括那些添加圆弧的函数: func addArc(center: CGPoint, radius: CGFloat, startAn
几个小时以来,我一直在努力解决这个问题。我试着阅读并寻找答案。我什至尝试过“走开,然后再回来”的方法,但没有奏效。我什至尝试过 Yaga 和冥想!我没有占上风。。 所以请各位高手赐教。 我只是想获得不
我有一个 View 被限制在顶部和底部,因此它的高度是动态的。然后我添加一个图层来添加一条垂直虚线。 以下是extension UIView中的代码: let shapeLayer = CAShape
我是一名优秀的程序员,十分优秀!