Сбой матча CGPoint - PullRequest
       1

Сбой матча CGPoint

0 голосов
/ 27 марта 2012

У меня есть изображение, к которому я добавил определенные пользовательские подпункты в виде точек.Существует также NSMutableArray, куда я добавляю соответствующий CGPoint.Я также добавляю установить тот же CGPoint, что и свойство в настраиваемом подпредставлении точки.

Когда я пытаюсь удалить случайную точку из общей суммы в массиве, я удаляю ее как из массива, так и удаляю соответствующее подпредставление из ImageView.если его свойство datapoint совпадает с тем же, которое было в массиве по этому индексу.

Это мой код в TouchStarted пользовательского ImageView для добавления точки данных.Существует также дополнительный код для сохранения последней добавленной точки желтого цвета, а старой - красной.

    SBPointView *pointView = [[SBPointView alloc] initWithFrame:CGRectMake(touchPoint.x - kPointViewSize/2, touchPoint.y - kPointViewSize, 5, 5)];
    pointView.backgroundColor = [UIColor yellowColor];
    pointView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;

    CGSize imageSize = self.image.size;
    CGRect frame = self.frame;
    CGAffineTransform transform = self.transform;
    CGAffineTransform scaleTransform = CGAffineTransformMakeScale(imageSize.width/frame.size.width, imageSize.height/frame.size.height);
    transform = CGAffineTransformConcat(transform, scaleTransform);

    CGPoint dataPoint = CGPointApplyAffineTransform(touchPoint, transform);//[mOfflineView convertPoint:touchPoint fromView:self];//[self convertPoint:touchPoint toView:mOfflineView];
    NSLog(@"**** Datapoint = %@", NSStringFromCGPoint(dataPoint));
    pointView.dataPoint = dataPoint;
    [mDataPoints addObject:NSStringFromCGPoint(dataPoint)];
    for (SBPointView *tempPointView in self.subviews) {
        if ([tempPointView isKindOfClass:[SBPointView class]]) {
            tempPointView.backgroundColor = [UIColor redColor];
        }
    }
    [self addSubview:pointView];
    [pointView release];

А вот мой код для удаления случайного PointView,

    -(void)deleteDatapointAtIndex:(NSUInteger)index{
        if (index < [mDataPoints count]) {
        CGPoint dataPoint = CGPointFromString([mDataPoints objectAtIndex:index]);
        for (SBPointView *subview in self.subviews) {
            if ([subview isKindOfClass:[SBPointView class]]) {

            if (subview.dataPoint.x == dataPoint.x && subview.dataPoint.y == dataPoint.y) {
                [mDataPoints removeObjectAtIndex:index];
                [subview removeFromSuperview];
                break;
            }
        }

    }

 }
}

Но по какой-то причине я не знаю почему, я не могу удалить определенные точки данных из массива, а также удалить подпредставления и условие if не выполнено, я делаю что-то не так, что я не вижу.

ОБНОВЛЕНИЕ: Я попытался поместить NSLog в цикл for, чтобы проверить, какие все точки данных, с которыми я проверяю, и какой пункт данных, который я выбрал из индекса, выясняется, что в тех случаях, когда происходит сбой IfУ меня есть такая точка, {483.2, 601.6}, и это точки слева {483.2, 601.6}, {483.2, 681.6}.

Совершенно очевидно, что мой CGPoint такой же, как и первый {483.2, 601.6}

и в условии if я проверяю равенство f и x, и y обеих точек CGPoints, но условие if все еще не выполняется!это как-то связано с потерей точности при преобразовании CGPoint в строку и обратно?

1 Ответ

0 голосов
/ 27 марта 2012

Похоже, это проблема сравнения чисел с плавающей точкой. Проще говоря, просто потому, что два числа с плавающей точкой должны быть равны, не означает, что они на самом деле.

float f1 = 21.9876;
float f2 = 22.2345;

Ваш калькулятор сообщит вам, что (f2 - f1) = 0,2469, но это не гарантируется на языке Си. Поместите следующее в файл с именем test.m

#import <CoreFoundation/CoreFoundation.h>
int main() {
        float f1 = 21.9876;
        float f2 = 22.2345;
        while (f2 - f1 != 0.2469)
                NSLog(@"HA");
        return 0;
}

А затем с помощью Terminal скомпилируйте его с GCC

$ gcc -framework Foundation test.m -o test; ./test

Ваш компьютер будет смеяться над вами, пытаясь сравнить два числа с "==". Более подходящий способ сравнить два числа с плавающей запятой - сделать что-то вроде этого:

float f1 = 21.9876;
float f2 = 22.2345;
if (fabs(f2 - f1) < 0.00001) // If the difference between them is this small, they are effectively equal

Конечно, технически правильная версия будет использовать FLT_EPSILON вместо 0,00001. Этот вопрос похож.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...