使用路径翻译视图(ObjectiveC,Cocoa)

时间:2013-11-23 02:19:52

标签: objective-c macos cocoa nsview

简短的故事是,我希望NSBezierPath的边界(我认为我的意思是边界而不是框架)来填充视图。像这样的东西: map

为了生成上面的图像,我使用Covert latitude/longitude point to a pixels (x,y) on mercator projection中的信息缩放/翻译了我创建的路径中的每个点。问题是这不可扩展(我将添加更多路径),我想在我的视图中轻松添加平移/缩放功能。另外,无论比例如何,我都希望笔划保持不变(即缩放时没有脂肪边界)。

我想我想在某个任意参考帧(例如经度和修改后的纬度)中生成可重用路径,而不是每次窗口改变时生成新路径。然后我可以翻译/缩放我的视图的坐标系以用路径填充视图。

所以我使用Apple's geometry guide来修改视图的框架。我得到了正确的翻译,但缩放失败了。

    [self setBoundsOrigin:self.path.bounds.origin];

map fail

    [self scaleUnitSquareToSize:NSMakeSize(1.5, 1.5)];

map fail

然后我在drawRect:方法中尝试了coordinate system transformation,结果只是结果类似。

NSAffineTransform* xform = [NSAffineTransform transform];
[xform translateXBy:(-self.path.bounds.origin.x) yBy:(-self.path.bounds.origin.y)];
[xform scaleXBy:1.5 yBy:1.5];
[xform concat];

map fail again

最后我尝试在drawRect中手动设置视图边界:但结果很丑陋且很慢!

arg

我知道我也可以转换NSBezierPath对象,我认为这样可行,但我宁愿转换视图一次,而不是循环并转换每个更新的每个路径。我认为我缺少大约三行代码,这些代码正是我正在寻找的。

编辑: 这是我正在使用的drawRect:方法:

- (void)drawRect:(NSRect)dirtyRect
{
//    NSAffineTransform* xform = [NSAffineTransform transform];
//    [xform translateXBy:-self.path.bounds.origin.x yBy:-self.path.bounds.origin.y];
//    [xform scaleXBy:1.5 yBy:1.5];
//    [xform concat];

[self drawBoundaries];
NSRect bounds = [self bounds];
[[NSColor blackColor] set];
[NSBezierPath fillRect:bounds];

// Draw the path in white
[[NSColor whiteColor] set];
[self.path stroke];

[[NSColor redColor] set];
[NSBezierPath strokeRect:self.path.bounds];
NSLog(@"path origin %f x %f",self.path.bounds.origin.x, self.path.bounds.origin.y);
NSLog(@"path bounds %f x %f",self.path.bounds.size.width, self.path.bounds.size.height);
}

1 个答案:

答案 0 :(得分:0)

我能够使用两个转换来使其工作。当我有许多转换路径和一个放大/缩小的窗口时,我试图避免这种情况以减少复杂性和计算。

- (void)transformPath:(NSBezierPath *)path
{
NSAffineTransform *translateTransform = [NSAffineTransform transform];
NSAffineTransform *scaleTransform = [NSAffineTransform transform];

[translateTransform translateXBy:(-self.path.bounds.origin.x)
                             yBy:(-self.path.bounds.origin.y)];

float scale = MIN(self.bounds.size.width / self.path.bounds.size.width,
                  self.bounds.size.height / self.path.bounds.size.height);
[scaleTransform scaleBy:scale];

[path transformUsingAffineTransform: translateTransform];
[path transformUsingAffineTransform: scaleTransform];
}