iphone - 使用 OpenGL 在 iPad 上绘图应用程序

标签 iphone xcode ipad opengl-es drawing

我正在使用 OpenGL 创建一个适用于 iPad 的绘图应用程序(文本)。我已经看过 Apple 的示例 GLPaint,我的应用程序现在基于该代码。我的应用程序应该只用于绘制文本,而不是用于绘制图片。

嗯,我的应用程序可以运行,我可以写一些文字。但文笔真的不好,写起来没有乐趣。绘图路径并不平滑,而是有角度的,因为我正在从一个点到另一个点绘制一条线。并且路径到处都有相同的宽度。我的想法是:当你写得快时,线条比你写得慢时要细。应该和用真笔写字是一样的体验。

怎样才能让路径看起来更平滑?如何根据书写速度改变线的宽度?

在这里你可以明白我的意思:

example

最佳答案

平滑绘图的最佳方法是使用贝塞尔曲线。这是我的代码。这是我在苹果开发网站上找到的修改版本,但我不记得原始链接:

CGPoint drawBezier(CGPoint origin, CGPoint control, CGPoint destination, int segments)
{
 CGPoint vertices[segments/2];
 CGPoint midPoint;
 glDisable(GL_TEXTURE_2D);
 float x, y;

 float t = 0.0;
 for(int i = 0; i < (segments/2); i++)
 {
  x = pow(1 - t, 2) * origin.x + 2.0 * (1 - t) * t * control.x + t * t * destination.x;
  y = pow(1 - t, 2) * origin.y + 2.0 * (1 - t) * t * control.y + t * t * destination.y;
  vertices[i] = CGPointMake(x, y);
  t += 1.0 / (segments);

 }
 //windowHeight is the height of you drawing canvas.
 midPoint = CGPointMake(x, windowHeight - y);
 glVertexPointer(2, GL_FLOAT, 0, vertices);
 glDrawArrays(GL_POINTS, 0, segments/2);
 return midPoint;
}

这将根据三分进行抽签。控件是您需要返回的中点。新的中点将与之前的不同。另外,如果你执行上面的代码,它只会绘制一半的线。下一笔将把它填满。这是必需的。我调用这个函数的代码(上面是C语言,这是Obj-C语言):

   //Invert the Y axis to conform the iPhone top-down approach
   invertedYBegCoord = self.bounds.size.height - [[currentStroke objectAtIndex:i] CGPointValue].y;
   invertedYEndCoord = self.bounds.size.height - [[currentStroke objectAtIndex:i+1] CGPointValue].y;
   invertedYThirdCoord = self.bounds.size.height - [[currentStroke objectAtIndex:i+2] CGPointValue].y;
   //Figure our how many dots you need
   count = MAX(ceilf(sqrtf(([[currentStroke objectAtIndex:i+2] CGPointValue].x - [[currentStroke objectAtIndex:i] CGPointValue].x) 
         * ([[currentStroke objectAtIndex:i+2] CGPointValue].x - [[currentStroke objectAtIndex:i] CGPointValue].x) 
         + ((invertedYThirdCoord - invertedYBegCoord) * (invertedYThirdCoord - invertedYBegCoord))) / pointCount), 1);

   newMidPoint = drawBezier(CGPointMake([[currentStroke objectAtIndex:i] CGPointValue].x, invertedYBegCoord), CGPointMake([[currentStroke objectAtIndex:i+1] CGPointValue].x, invertedYEndCoord), CGPointMake([[currentStroke objectAtIndex:i+2] CGPointValue].x, invertedYThirdCoord), count);

   int loc = [currentStroke count]-1;
   [currentStroke insertObject:[NSValue valueWithCGPoint:newMidPoint] atIndex:loc];
   [currentStroke removeObjectAtIndex:loc-1];

该代码将根据反转的 iPad 点获取中点,并将“控件”设置为当前点。

这将使边缘变得平滑。现在关于线宽,您只需要找到绘图的速度即可。最简单的方法就是找到线的长度。使用组件数学可以轻松完成此操作。我没有任何代码,但是 here是来自物理网站的组件数学入门书。或者,您可以简单地将(上面的)计数除以某个数字,以找出您需要的线的粗细(计数使用分量数学)。

我将点数据存储在名为 currentStroke 的数组中,以防它不明显。

这应该就是您所需要的。

编辑:

要存储点,您应该使用touchesBegin和touchesEnd:

- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
    self.currentStroke = [NSMutableArray array];
    CGPoint point = [ [touches anyObject] locationInView:self];
    [currentStroke addObject:[NSValue valueWithCGPoint:point]];
    [self draw];

}

- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
    CGPoint point = [ [touches anyObject] locationInView:self];
    [currentStroke addObject:[NSValue valueWithCGPoint:point]];
    [self draw];
}


- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    CGPoint point = [ [touches anyObject] locationInView:self];
    [currentStroke addObject:[NSValue valueWithCGPoint:point]];
    [self draw];
}

这几乎是一个完整的绘图应用程序。如果您正在使用 GL_Paint,那么您已经在使用点 Sprite ,该系统正是基于点 Sprite 而构建的。

关于iphone - 使用 OpenGL 在 iPad 上绘图应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4606680/

相关文章:

iOS:iPad ImageView 中的底部缩略图栏

iphone - UISegmentedControl的选定段

iphone - 使用 -dismissPopoverAnimated 关闭 UIPopoverController : won't call delegate?

ios - iPad Retina 启动图像——仅显示图像的上半部分

ios - 从另一个类重新加载核心数据 TableView

iphone - 在调用 respondsToSelector 之前检查委托(delegate)是否仍然存在

cocoa-touch - 如何以编程方式在使用 MonoTouch 启动时获得一个大的 iPad 窗口?

ios - 在 iOS swift3 中并行处理视频录制和通话功能

iphone - 按型号定位 iPhone 应用程序(例如 3G 与 3GS)

objective-c - 将 UIImageView 转换为 UIImage