Iphone 画笔对角线移动时画画不完整?
从Iphone 画笔对角线移动时画画不完整?,iphone,objective-c,ipad,Iphone,Objective C,Ipad,从currentPoint.x和currentPoint.y绘制到lastPoint.x和lastPoint.y 在对角线右上方或右下方,它给我的差距(空间)在画线,如下图所示 -(void)brushType{ UIGraphicsBeginImageContext(drawImage.frame.size); CGContextRef Mycontext = UIGraphicsGetCurrentContext();
currentPoint.x
和currentPoint.y
绘制到lastPoint.x
和lastPoint.y
在对角线右上方或右下方,它给我的差距(空间)在画线,如下图所示
-(void)brushType{
UIGraphicsBeginImageContext(drawImage.frame.size);
CGContextRef Mycontext = UIGraphicsGetCurrentContext();
int x, cx, deltax, xstep,y, cy, deltay, ystep,error, st, dupe;
int x0, y0, x1, y1;
x0 = currentPoint.x;
y0 = currentPoint.y;
x1 = lastPoint.x;
y1 = lastPoint.y;
// find largest delta for pixel steps
st =(abs(y1 - y0) > abs(x1 - x0));
// if deltay > deltax then swap x,y
if (st) {
(x0 ^= y0);
(y0 ^= x0);
(x0 ^= y0); //swap(x0, y0);
(x1 ^= y1);
(y1 ^= x1);
(x1 ^= y1); // swap(x1, y1);
}
deltax = abs(x1 - x0);
deltay = abs(y1 - y0);
error = (deltax / 4);
y = y0;
if (x0 > x1) {
xstep = -1;
}
else {
xstep = 1;
}
if (y0 > y1) {
ystep = -1;
}
else {
ystep = 1;
}
for ((x = x0); (x != (x1 + xstep)); (x += xstep))
{
(cx = x);
(cy = y); // copy of x, copy of y
// if x,y swapped above, swap them back now
if (st) {
(cx ^= cy);
(cy ^= cx);
(cx ^= cy);
}
(dupe = 0); // initialize no dupe
if(!dupe) {
CGContextSetRGBStrokeColor(Mycontext, 0.0, 0.0, 0.0, 1.00f);
CGContextMoveToPoint(Mycontext, cx+brushSize*4,cy-brushSize/2);
CGContextAddLineToPoint(Mycontext, cx-brushSize/2, cy+brushSize*4);
}
(error -= deltay); // converge toward end of line
if (error < 0) { // not done yet
(y += ystep);
(error += deltax);}
}
CGContextStrokePath(Mycontext);
[drawImage.image drawInRect:CGRectMake(0, 0, drawImage.frame.size.width, drawImage.frame.size.height)];
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lastPoint = currentPoint;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
brushSize = 4;
mouseSwiped = YES;
UITouch *touch = [touches anyObject];
currentPoint = [touch locationInView:drawImage];
currentPoint.y -= 20;
[self brushType];
}
-(void)画笔类型{
UIGraphicsBeginImageContext(drawImage.frame.size);
CGContextRef Mycontext=UIGraphicsGetCurrentContext();
int x、cx、deltax、xstep、y、cy、deltay、ystep、error、st、dupe;
int x0,y0,x1,y1;
x0=当前点.x;
y0=当前点y;
x1=最后一点x;
y1=最后一点y;
//查找像素步长的最大增量
st=(abs(y1-y0)>abs(x1-x0));
//如果deltay>deltax,则交换x,y
if(st){
(x0^=y0);
(y0^=x0);
(x0^=y0);//交换(x0,y0);
(x1^=y1);
(y1^=x1);
(x1^=y1);//交换(x1,y1);
}
deltax=abs(x1-x0);
deltay=abs(y1-y0);
错误=(deltax/4);
y=y0;
如果(x0>x1){
xstep=-1;
}
否则{
xstep=1;
}
如果(y0>y1){
ystep=-1;
}
否则{
ystep=1;
}
对于((x=x0);(x!=(x1+xstep));(x+=xstep))
{
(cx=x);
(cy=y);//x的副本,y的副本
//如果x,y在上面交换,现在将它们交换回来
如果(st){
(cx^=cy);
(cy^=cx);
(cx^=cy);
}
(dupe=0);//初始化无dupe
如果(!dupe){
CGContextSetRGBStrokeColor(Mycontext,0.0,0.0,1.00f);
CGContextMoveToPoint(Mycontext,cx+brushSize*4,cy brushSize/2);
CGContextAddLineToPoint(Mycontext,cx-brushSize/2,cy+brushSize*4);
}
(error-=deltay);//向行尾收敛
如果(错误<0){//尚未完成
(y+=ystep);
(错误+=deltax);}
}
CGContextStrokePath(Mycontext);
[drawImage.image drawInRect:CGRectMake(0,0,drawImage.frame.size.width,drawImage.frame.size.height)];
drawImage.image=UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsSendImageContext();
lastPoint=currentPoint;
}
-(无效)触摸移动:(NSSet*)触摸事件:(UIEvent*)事件{
刷子大小=4;
鼠标擦拭=是;
UITouch*touch=[触摸任何对象];
currentPoint=[触摸位置查看:drawImage];
电流点y-=20;
[自刷式];
}
如果有人有想法,请帮助我解决这个问题 我发现你的函数有很多问题,其中大部分都是粗制滥造的。您正在使用XOR交换,这使得代码很难读取。您在方法的顶部声明了所有变量,这使得理解每个变量的生存期变得更加困难。您将不必要的括号放得到处都是,这使得代码更难阅读。在循环中重复调用
CGContextSetRGBStrokeColor
,但只需设置一次笔划颜色。因此,首先让我们重写您的方法来解决这些问题:
static inline void swap(int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}
-(void)brushType {
int x0 = currentPoint.x;
int y0 = currentPoint.y;
int x1 = lastPoint.x;
int y1 = lastPoint.y;
int deltax = abs(x1 - x0);
int deltay = abs(y1 - y0);
int needSwap = deltay > deltax;
if (needSwap) {
swap(&x0, &y0);
swap(&x1, &y1);
swap(&deltax, &deltay);
}
int error = deltax / 4;
int y = y0;
int xstep = x0 > x1 ? -1 : 1;
int ystep = y0 > y1 ? -1 : 1;
CGSize size = self.drawImage.bounds.size;
UIGraphicsBeginImageContext(size); {
CGContextRef gc = UIGraphicsGetCurrentContext();
for (int x = x0; x != x1 + xstep; x += xstep)
{
int cx = x;
int cy = y;
if (needSwap)
swap(&cx, &cy);
CGContextMoveToPoint(gc, cx + brushSize*4, cy - brushSize/2);
CGContextAddLineToPoint(gc, cx - brushSize/2, cy + brushSize*4);
error -= deltay; // converge toward end of line
if (error < 0) { // not done yet
y += ystep;
error += deltax;
}
}
[UIColor.blackColor setStroke];
CGContextStrokePath(gc);
[self.drawImage.image drawInRect:CGRectMake(0, 0, size.width, size.height)];
self.drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
} UIGraphicsEndImageContext();
lastPoint = currentPoint;
}
如果您使用此版本的方法,您会发现它看起来更好,但仍然不太完美:
我认为,问题在于对角线笔划是使用抗锯齿绘制的,而抗锯齿是一种近似值。如果你画了两条相隔1点的宽度为1的线,那么每一条线构成公共像素的部分颜色就不会完美叠加
一个简单,俗气的方法来修复它是让你的笔划宽度稍微宽一点。只需将此添加到CGContextStrokePath
之前:
CGContextSetLineWidth(gc, 1.1);
结果:
我知道这与真正的问题无关,但你真的知道。它使您的代码更慢、更不安全、更不可读。
CGContextSetLineWidth(gc, 1.1);