如何弯曲CGMutablePath?

2023-11-25

具有以下形状:

enter image description here

我想知道你如何让它像这样弯曲:

enter image description here

也类似:

enter image description here

我假设所有的圆/线都被打包成一个CGMutablePath,然后对它应用某种曲线、圆弧或四边形曲线,尽管我很难复制它。有谁知道如何做到这一点?


在第一个示例中,您从具有多个闭合子路径的路径开始。显然,您想要扭曲子路径的中心,但保持各个子路径相对于其(新)中心不扭曲。我将忽略这一点,因为即使没有它,解决方案也已经非常复杂。

那么,让我们考虑一下如何定义“扭曲场”。我们将使用三个控制点:

example with control points

扭曲使固定点保持不变。它将起点移动到终点rotation and scaling, not通过简单地插值坐标。

此外,它还根据距固定点的距离应用旋转和缩放。而且不仅仅是基于简单的欧几里得距离。请注意,我们不想对图片中“V”形状的顶部端点应用任何旋转或缩放,即使这些端点距固定点有可测量的欧几里德距离。我们想要测量沿fixedPoint->startPoint向量的距离,并随着距离的增加应用更多的旋转/缩放。

这一切都需要一些相当重的三角学。我不会尝试解释细节。我只是要把代码转储给你,作为一个类别UIBezierPath:

UIBezierPath+Rob_warp.h

#import <UIKit/UIKit.h>

@interface UIBezierPath (Rob_warp)

- (UIBezierPath *)Rob_warpedWithFixedPoint:(CGPoint)fixedPoint startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint;

@end

UIBezierPath+Rob_warp.m

请注意,您将需要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在我的测试程序中处于用户控制之下。在模拟器中看起来像这样:

demo with V

气泡型路径如下所示:

demo with bubbles

您可以在这里找到我的测试项目:https://github.com/mayoff/path-warp

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何弯曲CGMutablePath? 的相关文章

  • UIButton 图像调整大小/缩放以适合

    我有一个非常严重的问题 我不知道如何解决 我正在对 UIButtons 框架进行动画处理 当我对其进行动画处理时 我希望按钮中的图像缩放到与按钮相同的大小 它无需在我的 iPhone 模拟器上执行任何操作即可运行 但是当我在 iPad 模拟
  • 使用 CommonCrypto 的 Swift AES 加密

    我正在开发一个 iOS 应用程序代码7 1 with 斯威夫特2 1我正在尝试进行简单的加密AES 128 位 and PKCS7填充使用通用加密库 该代码有效 但每次我尝试投射NSData反对NSString然后对于 String 我得到
  • MacOS X 和 iOS 中的 ASLR 究竟随机化了什么

    有谁有最新 Mac OS 10 7 和 iOS 6 0 在什么情况下随机化的文档链接 我是说 我想看一个列表 类似的东西 代码段 在情况 A B C 中 堆栈 始终 Heap 数据段 从不 最好每个东西有多少位随机化 我能找到的只是这样的内
  • 如何关闭 Google Analytics for Firebase 中的数据阈值

    我需要帮助将 firebase 分析集成到我的 flutter 项目中 编写了一些自定义事件并希望使用此事件中的数据 这就是为什么我创建指标和维度但它不起作用 因为我获得了数据阈值 并收到了此消息 当启用 Google 信号并且您在指定日期
  • 防止 Realm 在更新对象时覆盖属性

    我已经在 iOS 中设置了一个 REST API 来连接领域对象 然而 我发现在我的对象中创建最喜欢的标志存在问题 我创建了一个最喜欢的布尔值 但是每次从 API 更新该对象时 它都会再次将最喜欢的值设置为默认 false 在这里 我希望这
  • HTML 5 + iOS - 创建混合应用程序

    我正在尝试将我的本机 iOS 应用程序转换为使用 HTML 5 的混合应用程序 经过研究后我最终得到了jQuery 移动 phoneGap 我的问题是 是否可以将 html 5 和本机 iOS 功能混合在一个单一的版本中 看法 例如我可以使
  • 转发 UIAlertView 的可变参数

    我正在尝试设置一个非常简单的UIAlertView带有文本编辑 确定和取消按钮 我想根据文本编辑的内容禁用确定按钮 为了能够保留委托 以便他不会在警报视图之前消失 从而在用户对警报视图执行某些操作时立即导致崩溃 我对其进行了子类化 现在 我
  • App Store Connect 上传错误“您尚未获得云管理分发证书的访问权限”

    使用 Xcode 将 iOS 应用程序上传到 App Store Connect 自动管理签名 并收到此错误 查找和生成签名资产时发生以下错误 与苹果通讯失败 您尚未获得云管理分发证书的访问权限 请联系您团队的帐户持有人或管理员以授予您访问
  • Dropbox iOS SDK 始终为 isLinked 返回“YES”:

    我正在使用 iOS Dropbox SDK 想要检查我的应用程序是否已与 Dropbox 帐户链接 所以我这样做 if self isLinked NSLog linked However self isLinked总是返回YES 即使在清
  • Three20 和 iOS 6 不工作

    我刚刚尝试了我的一个项目 其中包含 Three20 但它似乎无法编译 给我构建错误 似乎是因为一些 UITouch 界面发生了变化 想知道是否有快速修复方法可以做到这一点 看来问题是在这里 UITouch ivars 已从 iOS 6 SD
  • 何时以及为何使用多个 NSManagedObjectContext?

    基本上 我在我的应用程序中只使用了一个 moc 但我认为在某些情况下我应该使用多个 NSManagedObjectContext 什么时候应该使用多个 NSManagedObjectContext 我听说在某些情况下我应该使用 3 moc
  • 修改多张照片时只有一个 iOS 权限对话框

    我的应用程序允许用户从相机胶卷中选择多个图像并对这些图像应用编辑 但是 它会提示用户获得每个图像编辑的权限 编辑用户图像时是否可以只显示一个权限对话框 如果是 我该如何将我的编辑分组为一项权限 这是我的应用程序的屏幕截图 我在应用商店中发现
  • “找不到开发者磁盘映像”

    最近我收到错误 找不到开发人员磁盘映像 我认为自从我将 iPhone 上的 iOS 更新到 9 1 后就会发生这种情况 如何解决该问题并使 Xcode 支持 iOS 9 1 设 备 Xcode 7 0 1 和 iOS 9 1 不兼容 您需要
  • 在 Cordova / PhoneGap 中生成 iOS 和 Android 图标

    我有一个新创建的 Cordova 项目 其中包含以下内容config xml设置 使用来自http docs phonegap com en edge config ref images md html http docs phonegap
  • 扩展中的 Swift 覆盖函数

    如果我有课 class Spaceship
  • 在 wkwebview 中启用摄像头和麦克风访问

    我有一个针对移动设备优化的网络应用程序 它利用getUserMedia访问网络摄像头和麦克风资源 我正在将这个应用程序包装在WKWebView因为我想提供原生应用程序体验 我知道 iOS 不允许通过浏览器访问相机 但是有什么方法可以使用本机
  • 如何使 CSS 动画/过渡以固定速度而不是固定持续时间播放? [复制]

    这个问题在这里已经有答案了 我有一个 CSS 动画 可以使元素沿直线移动未定义的距离 据我所知 动画具有固定的持续时间 因此无论元素必须移动多远 动画始终需要相同的时间来运行 我该如何制作才能使动画没有固定的duration 但有固定的运动
  • Swift - 带循环的多个链 http 请求

    两天以来 我感觉我正在搜索整个网络来解决多个 http 请求的问题 所以我的工作流程如下所示 将图像上传到服务器 响应 XML 格式和任务 ID 使用任务 ID 向服务器发出 GET 请求 以检查该任务的状态 响应 XML 格式 其中状态可
  • UIPopViewController 不工作

    我有一个 xib 文件 其中有 h 和 m 链接 在 xib 中有一个带有 textView 的 UIView 我想要对该视图执行的操作是 当您单击按钮时将其作为 UIPopViewController 打开 这是我的代码 IBAction
  • 如何在 iOS 11 上的 Swift 中获取 FLAC 文件元数据?

    我需要获取 FLAC 文件的元数据 我尝试了以下代码 let item AVPlayerItem url URL fileURLWithPath path let commonMetadata item asset commonMetada

随机推荐