2014-09-11 4 views
1

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

В приложении, которое я разрабатываю, мы имеем значение, которое может колебаться где угодно между 0 и заданным максимумом (при тестировании он обычно парит около 100, так что давайте просто скажем 100). Этот диапазон данных является непрерывным, что означает, что существует бесконечное количество возможных значений - если оно находится между 0 и 100, это возможно.

В настоящее время любое значение, возвращаемое из этого, отображается в другой диапазон, который также является непрерывным, от 1000 до 200. Поэтому, если значение из первого набора равно 100, я сопоставляю его с 200, и если значение из первый набор равен 0, он отображается на 1000. И, конечно, все между ними. Это то, что код выглядит следующим образом:

-(float)mapToRange:(float)val withMax:(float)maxVal{ 
    // Establish range constants. 
    const int upperBound = 1000; 
    const int lowerBound = 200; 
    const int bandwidth = upperBound - lowerBound; 

    // Make sure we don't go above the calibrated maximum. 
    if(val > maxVal) 
     val = maxVal; 

    // Scale the original value to our new boundaries. 
    float scaled = val/maxVal; 
    float ret = upperBound - scaled*bandwidth; 

    return ret; 
} 

Теперь, что я хочу сделать, это сделать так, чтобы более высокие исходные значения (ближе к 100) увеличение с большим шагом, чем нижние исходные значения (ближе к 0) , Если я постепенно начну уменьшаться с 100 до 0 с постоянной скоростью, новые значения, начинающиеся с 200, быстро начнут двигаться к 1000 сначала, но идут с меньшими шагами, чем ближе они доходят до 1000. Каким будет лучший способ сделать это ?

ответ

1

Ваша ценность scaled - это в основном значение 0-100, представленное в диапазоне 0-1, с которым хорошо работать. Попытайтесь повысить это до целочисленной мощности, и результат будет увеличиваться быстрее около 1 и медленнее около 0. Чем выше мощность, тем больше эффект. Так что-то вроде:

float scaled = val/maxVal; 
float bent = scaled*scaled*scaled*scaled; // or however you want to write x^4 
float ret = upperBound - bent*bandwidth; 

Вот эскиз идеи: enter image description here

То есть, пролет A to B, карты с меньшим пролетом a to b, в то время пролета C to D карты с большим пролетом c to d. Чем больше мощность полинома, тем больше кривая будет согнута в нижнем правом углу.

Преимущества использования 0 в 1 диапазона является то, что конечные точки остаются неподвижными, так как x^n=x когда x является 0 или 1, но это, конечно, не нужно как-то может быть компенсировано за счетом соответствующего смещения и масштабированием ,

Обратите внимание, что эта карта не симметрична (хотя мой рисунок выглядит так), хотя можно выбрать симметричную кривую. Если вы хотите криволинейно наклониться в другую сторону, выберите мощность меньше 1.

Смежные вопросы