2009-08-24 8 views
4

Я пишу iPhone-код, который нечетко распознает, является ли строка с прямой видимостью прямолинейной. Я получаю подшипник двух конечных точек и сравниваю его с 0, 90, 180 и 270 градусами с допуском 10 градусов плюс или минус. Прямо сейчас я делаю это с кучей блоков, которые кажутся супер неуклюжими.Как определить, находится ли число в процентах от другого номера

Как написать функцию, которая, учитывая подшипник 0..360, допуска процент к (скажем, 20% = (от -10 ° до + 10 °)) и прямой угол , как 90 градусов , возвращает ли подшипник в пределах допуска?

Обновление:Я, возможно, слишком специфичен. Я думаю, что хорошая, общая функция, которая определяет, находится ли число в процентах от другого числа, имеет полезность во многих областях.

Например: Является ли число swipeLength в 10% из maxSwipe? Это было бы полезно.

BOOL isNumberWithinPercentOfNumber(float firstN, float percent, float secondN) { 
     // dunno how to calculate 
} 

BOOL result; 

float swipeLength1 = 303; 
float swipeLength2 = 310; 

float tolerance = 10.0; // from -5% to 5% 
float maxSwipe = 320.0; 

result = isNumberWithinPercentOfNumber(swipeLength1, tolerance, maxSwipe); 
// result = NO 

result = isNumberWithinPercentOfNumber(swipeLength2, tolerance, maxSwipe); 
// result = YES 

Вы видите, что я получаю?

+0

Существуют ли углы на 180 градусов друг от друга, например, вертикальная линия, оттянутая сверху вниз 90 и одна и та же линия, оттянутая снизу вверх 270, или они одинаковы? –

+1

Вы действительно имеете в виду толерантность как процент? Процент того, что? Я думаю, что простое угловое различие имеет больше смысла в качестве порога. –

+1

Связанный вопрос: http://stackoverflow.com/questions/338762/how-do-you-calculate-the-angle-between-two-normals-in-glsl (это показывает, как вычислить угол между двумя векторами) , –

ответ

0

20% в качестве десятичного числа равно 0,2. Просто разделите на 100.0, чтобы получить десятичную. Разделите на 2.0, чтобы получить половину допустимого диапазона. (Объединено в делитель 200.0)

Оттуда добавьте и вычтите из 1.0, чтобы получить значения 90% и 110%. Если первое число находится между диапазонами, то у вас оно есть.

BOOL isNumberWithinPercentOfNumber(float firstN, float percent, float secondN) { 
     float decimalPercent = percent/200.0; 
     float highRange = secondN * (1.0 + decimalPercent); 
     float lowRange = secondN * (1.0 - decimalPercent); 
     return lowRange <= firstN && firstN <= highRange; 
} 

Примечание: здесь нет ошибок для NaN или отрицательных значений. Вы хотите добавить это для производственного кода.

Обновление: чтобы сделать проценты для включения обоих диапазонов +/-.

+0

Я не пояснил, что если допуск составляет 20%, это означает, что диапазон составляет от -10% до + 10% Мои извинения – willc2

+0

Хорошо, просто разделите на 200.0 вместо 100.0 то –

+0

Это не работает с двумя отрицательными числами. Например, если вы переходите в -20 и -20, он возвращает false. – rolls

4
int AngularDistance (int angle, int targetAngle) 
{ 

    int diff = 0; 
    diff = abs(targetAngle - angle) 

    if (diff > 180) diff = 360 - diff; 

    return diff; 
} 

Это должно работать для любых двух углов.

+0

Какой вопрос вы отвечаете? – willc2

+0

Это оригинальный вопрос о сравнении подшипника с целью (0 °, 90 °, 180 °, 270 °). Функция дает вам угол между обоими, что вы можете сравнить с вашим допуском, скажем, 10 °. Как отметил Джим Льюис, проценты малозначительны для углов и они, как правило, немного сложнее (из-за их округлости: например, 350 ° + 20 ° = 10 °). –

0

Ответ на ваш рафинированный/новый вопрос:

bool isNumberWithinPercentOfNumber (float n1, float percentage, float n2) 
{ 

if (n2 == 0.0) //check for div by zero, may not be necessary for float 
    return false; //default for a target value of zero is false 
else 
    return (percentage > abs(abs(n2 - n1)/n2)*100.0); 
} 

Чтобы объяснить, вы берете на себя абсолютную разницу между тестом и целевым значением, и разделить его целевое значение (два «abs'olute звонков сделать уверен, что это работает и с отрицательными целевыми и тестовыми номерами, но не с отрицательными процентами/допусками). Это дает вам процент разницы, выраженный как десятичная дробь, умножает ее на 100, чтобы дать «общее» выражение процента (10% = 0,10),