2009-06-24 2 views
4

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

Graph http://img87.imageshack.us/img87/7886/control.png

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

Я знаю, что экспоненциальная слишком крутая, но не может показаться, что она направлена ​​вперед. Любые предложения, пожалуйста?

+0

Почему C# тег? В конечном итоге ваше решение может быть C#, но я ничего не вижу в проблеме, которая является C#. Удаление тега ... – abelenky

+0

Объясните поведение, которое вы хотите. (кроме начала/конечных точек) Является ли он экспоненциальным? Полином? логарифмическая? Похоже, что уклон около 0 линейный, а затем масштабируется вверх по мере необходимости для достижения конечной точки. –

+0

... или интерполяция между линейным и чем-то. –

ответ

3

Кривые, которые вы проиллюстрировали, очень похожи на кривые gamma correction.Идея заключается в том, что минимальный и максимальный диапазон остается таким же, как и вход, но середина согнута, как у вас на графиках (что я мог бы отметить, это не круговая дуга, которую вы получите от реализации косинуса).

Графически это выглядит следующим образом:

alt text http://upload.wikimedia.org/wikipedia/commons/thumb/7/74/GammaFunctionGraph.svg/200px-GammaFunctionGraph.svg.png

Таким образом, с вдохновением, вот математика ...

Если значения х в диапазоне от 0 до 1, то функция достаточно прост:

y = f(x, gamma) = x^gamma 

Добавить Xmax значение для масштабирования (то есть х = 0 до 100), а функция принимает вид:

y = f(x, gamma) = ((x/xmax)^gamma) * xmax 

или в качестве альтернативы:

y = f(x, gamma) = (x^gamma)/(xmax^(gamma - 1)) 

Вы можете принять это шаг вперед, если вы хотите добавить ненулевую XMIN.

Когда гамма равна 1, линия всегда идеально линейна (y = x). Если x меньше 1, ваша кривая наклоняется вверх. Если x больше 1, ваша кривая отклоняется вниз. Возвращаемое значение гаммы преобразует значение обратно в исходное (x = f (y, 1/g) = f (f (x, g), 1/g).

Просто отрегулируйте значение гаммы согласно по вашему вкусу и потребностям приложений. Поскольку вы хотите предоставить пользователю несколько вариантов «повышения чувствительности», вы можете захотеть предоставить пользователям выбор в линейном масштабе, скажем, от -4 (наименее чувствительный) до 0 (без изменений) до 4 (наиболее чувствительных) и масштабировать ваши внутренние гамма-значения с помощью функции мощности. Другими словами, дайте пользователю выбор (-4, -3, -2, -1, 0, 1, 2, 3 , 4), но перевести, что гамма-значений (5,06, 3,38, 2,25, 1,50, 1,00, 0,67, 0,44, 0,30, 0,20)

кодирования, что в C# может выглядеть примерно так:.

public class SensitivityAdjuster { 
    public SensitivityAdjuster() { } 
    public SensitivityAdjuster(int level) { 
     SetSensitivityLevel(level); 
    } 
    private double _Gamma = 1.0; 
    public void SetSensitivityLevel(int level) { 
     _Gamma = Math.Pow(1.5, level); 
    } 
    public double Adjust(double x) { 
     return (Math.Pow((x/100), _Gamma) * 100); 
    } 
} 

Чтобы использовать его, создайте новый SensitivityAdjuster, установите уровень чувствительности в соответствии с предпочтениями пользователя (либо с использованием конструктора, либо с помощью метода, и от -4 до 4, вероятно, будут разумными значениями уровня) и вызовите Adjust (x) на получить скорректированное выходное значение. Если вам нужен более широкий или более узкий диапазон разумных уровней, вы уменьшили бы или увеличили бы это значение 1,5 в методе SetSensitivityLevels. И, конечно же, 100 представляет ваше максимальное значение x.

+0

Это было решение (для меня в любом случае). Я пробовал это, и он работал, все, что мне нужно. Я не могу, чтобы ты достаточно Пол, я был похож на собаку, «преследующую ее хвост» на этом. Еще раз спасибо! – user68528

0

Возможно, вы ищете что-то вроде polynomial interpolation. Квадратичная/кубическая/квартичная интерполяция должна дать вам вид кривых, которые вы видите в вопросе. Различия между тремя кривыми, которые вы показываете, вероятно, можно достичь, только скорректировав коэффициенты (которые косвенно определяют крутизну).

+0

Я посмотрел на это, и интерполяция, очень похожая на подгонку кривой, - это случай, когда у вас есть несколько или более дискретных точек, которые вы пытаетесь связать вместе. V Затем вы используете m = изменение в x/изменение y различать. Мое случайное простое, где я хочу либо разрешить пользователю вводить переменную, либо выбирать из перечисления, которое имеет крутые, средние и мягкие (ужасные имена, которые я знаю), чтобы они могли выбирать крутизну кривой, так же, как отключить контроль тяги на автомобиле и не интерполировать точки, поскольку в настоящее время их нет. Мне нужно их генерировать. – user68528

+1

Попробуйте кривую Безье: http://en.wikipedia.org/wiki/Bézier_curve –

+0

Спасибо, я попробую это и предложения AakashM. – user68528

0

График y = x^p для x от 0 до 1 будет делать то, что вы хотите, поскольку вы меняете p от 1 (что даст красную линию) вверх. По мере того как p увеличивает кривую, будет «вдаваться» все больше и больше. p не обязательно должно быть целым числом.

(Вы должны будете масштабировать, чтобы получить от 0 до 100, но я уверен, что вы можете работать, что из)

+0

x^p где p> 1 дает вам наклон 0 около 0. Это не похоже на кривые, которые вы нарисовали. –

1

Я предлагаю простую формулу, которая (я верю) захватывает ваше требование. Чтобы иметь полный «круг четверти», который является вашим крайним случаем, вы должны использовать (1-cos((x*pi)/(2*100)))*100.

Я предлагаю, чтобы вы взяли средневзвешенное значение между y = x и y = (1-cos ((x * pi)/(2 * 100))) * 100. Например, чтобы иметь очень близка к линейной (99% линейной), возьмите:

y = 0.99*x + 0.01*[(1-cos((x*pi)/(2*100)))*100] 

Или в более общем плане, скажем, уровень линейности L, и это в интервале [0, 1], ваша формула будет быть:

y = L*x + (1-L)*[(1-cos((x*pi)/(2*100)))*100] 

EDIT: Я изменил cos(x/100) к cos((x*pi)/(2*100)), потому что для сов приводит к быть в диапазоне [1,0] Х должно быть в диапазоне [0, р/2], а не [0 , 1], извините за первоначальную ошибку.

+0

Я люблю простой форум. Я уверен, что это будет хорошо завтра. спасибо! – user68528

0

я голосовать за общую идею Rax Olgud, в одной модификации:

y = alpha * x + (1-alpha)*(f(x/100)*100) 

alt text http://www4c.wolframalpha.com/Calculate/MSP/MSP4501967d41e1aga1b3i00004bdeci2b6be2a59b?MSPStoreType=image/gif&s=6

, где F (0) = 0, F (1) = 1, F (X) суперлинеен, но я не знаю, откуда взялась идея «четверть круга» или почему 1-cos (x) будет хорошим выбором.

Я хотел бы предложить п (х) = х к где к = 2, 3, 4, 5, все, что дает вам желаемый degre крутизны для & альфа = 0. Выберите значение для к, как неподвижная номер, затем измените α, чтобы выбрать свою конкретную кривую.

+0

Я считаю, что Ракс Ольгуд выбрал четверть круга и круговую функцию, потому что круговая функция движется медленно, когда она находится около одной оси и наиболее быстро, когда она находится рядом с другой осью. – Nosredna

0

Для таких проблем я часто получаю несколько точек от кривой и бросаю ее через программу подгонки кривой. Их там множество. Here's one with a 7-day free trial.

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

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