Проектирование фильтра путем распределения полюсов и нулей по параметрическим кривым


17

N - го порядка Баттерворта фильтр низких частот с частотой среза могут быть сконструированы путем распределения полюсов равномерно по параметру на S-плоскости параметрической кривой , который является полукругом:ωcN0<α<1f(α)=ωcei(π/2+πα)

Фильтр Баттерворта
Рисунок 1. Полюса фильтра Баттерворта 6-го порядка (CC BY-SA 3.0 Fcorthay)

Примечательно, что одну и ту же параметрическую кривую можно использовать для любой степени фильтрации дающей ненормализованную передаточную функцию:N

(1)H(s)=k=1N1sf(2k12N),

и что полученный фильтр всегда является фильтром Баттерворта. То есть ни один другой фильтр с таким же числом полюсов и нулей не имеет большего числа исчезающих производных частотной характеристики по частотам на частотах и . Набор фильтров Баттерворта с одинаковой частотой среза образует подмножество фильтров Баттерворта, для которых параметрическая кривая является уникальной. Подмножество бесконечно, так как не имеет верхней границы.ω=0ω=ωcf(α)N

В более общем смысле, не считая полюсов и нулей на бесконечности, если они не вытекают из параметрических кривых, любой фильтр с полюсами и нулями, где - целое число, а - неотрицательная дробь целых чисел, имеет ненормализованную передаточную функцию вида:NNpNNzNNz/Np

(2)H(s)=k=1NNz(sfz(2k12NNz))k=1NNp(sfp(2k12NNp)),

где и являются параметрическими кривыми, которые могут описывать распределение полюсов и нулей в пределе .fp(α)fz(α)N

  • Вопрос 1: Какие другие типы фильтров, кроме Баттерворта, определенные некоторым критерием оптимальности, имеют бесконечные подмножества, каждое из которых определяется дробью и парой параметрических кривых и на уравнение. 2, с фильтрами, отличающимися только на ? Nz/Npfp(α)fz(α)NЧебышевские фильтры типа I , да; с ними полюса находятся на одной половине эллипса с параметрическим углом . Фильтры Баттерворта и Чебышева типа I и типа II являются частными случаями эллиптических фильтров . Просто чтобы прояснить, под «бесконечными подмножествами» я подразумеваю не бесконечное количество подмножеств, а подмножества бесконечного размера.α
  • Вопрос 2. Имеют ли такие бесконечные подмножества не-Баттерворт-не-Чебышевские эллиптические фильтры?
  • Вопрос 3. Каждый ли эллиптический фильтр входит в такое бесконечное подмножество?

Если бесконечный набор всех эллиптических фильтров представляет собой объединение взаимоисключающих и исчерпывающих бесконечных подмножеств эллиптических фильтров, каждый из которых определяется одной параметрической кривой для размещения полюсов и одной параметрической кривой для размещения нулей, а также является неприводимой долей числа от нулей до полюсов, то численная оптимизация для получения эллиптических фильтров может быть выполнена путем оптимизации параметрических кривых, а не фильтров для какого-либо конкретного порядка. Оптимальные кривые могут быть повторно использованы для нескольких порядков фильтров, сохраняя оптимальность. «Если» выше, я задаю вопросы 2 и 3. Вопрос 1 касается расширения подхода к другим критериям оптимальности.

Конечно, графики эллиптических фильтров с нулевым полюсом выглядят так:

Эллиптический фильтр
Рисунок 2. Логарифмическая величина эллиптического фильтра нижних частот в s-плоскости. Белые точки - это полюсы, а черные - нули.

Один вывод это то, что в уравнении. 1, определенные значения и, следовательно, определенные положения полюсов и нулей должны быть разделены между несколькими фильтрами:α

альфа и степень фильтра
Рисунок 5. Значение , полученное с помощью кривого параметра для разной степени фильтра . Обратите внимание, что для нескольких порядков фильтрации мы имеем, например, или иN α = 0,5 α = 0,25 α = 0,75.αNα=0.5α=0.25α=0.75.

В частности, для фильтра, который имеет полюсов или нулей, они все также появляются в фильтрах, которые имеют одинаковых, где - любое положительное целое число.3 n N nN3nNn


Демонстрируя чрезвычайно сухой юмор, по запросу пользователя A_A я рассмотрел лемнискату Бернулли в качестве примера параметрической кривой s-плоскости:

Лемнискат Бернулли
Рисунок 4. Лемнискат Бернулли

Следующая параметрическая кривая дает левую половину лемнискаты Бернулли с параметром и начинающимся и заканчивающимся при :с = 00<a<1s=0

f(α)=2sin(πα)cos2(πα)+1+i2sin(πα)cos(πα)cos2(πα)+1

Используя эту параметрическую кривую для полюсов, мы хотели бы как-то сравнить между различными амплитудно-частотные характеристики, полученные с помощью уравнения. 1. Один из способов - посмотреть на й корень амплитудно-частотной характеристики. Это также позволяет нам посмотреть, как все выглядит в :N | H ( i ω ) | 1 / N N NN|H(iω)|1/NN

Частотная характеристика корня N-й величины
Рисунок 3. й корень амплитудно-частотной характеристики полюсного фильтра, полюса которого распределены по лемнискате Бернулли равномерно по отношению к параметру кривой. На более высоких частотах, чем показанные на графике, все графики имеют наклон -6 дБ / октаву (-20 дБ / декада). В пределе в производной графика есть разрыв при когда лемнискат (дважды) пересекает мнимую ось s-плоскости в этой точке.N N ω = 0 s = 0NNNω=0s=0

Предел го корня величины передаточной функции (уравнение 1) как был рассчитан как:N NN

(3)limN|H(s)|1/N=01|1sf(α)|dα=e01log(|sf(α)|)dα,

где представляет интеграл произведения, который можно вычислить с помощью натурального логарифма, интегрирования и экспоненциальной функции. Как часто с интеграцией, не было символического выражения для интеграла, который должен был быть численно оценен для лемнискаты Бернулли. В общем, результирующие амплитудно-частотные характеристики выглядят довольно бесполезно для этой «случайно выбранной» параметрической кривой.


Пользователь Matt L. упомянул фильтры Лернера. Что я нашел о них, с небольшой интерпретацией:

H(s)=k=1mBk(s+a)(s+a)2+bk2B1=1/2,Bm=(1)m+12Bi=(1)k+1 for k=2,,m1,

с положениями полюсов такими что для всех . Похоже, что эти полюсы, хотя и распределены по линии, являются не полюсами полного фильтра, а полюсами параллельных секций. Я не подтвердил, каковы полюсы всей системы или являются ли фильтры Лернера в каком-либо полезном смысле оптимальными. Ссылка: CM Rader, B. Gold, Техническая записка MIT Lincoln Laboratory 1965-63, Методы проектирования цифровых фильтров , 23 декабря 1965 года.b m - b m - 1 = b 2 - b 1 = 1a+ibkbmbm1=b2b1=12(bkbk1)3<k<m1


4
Мой английский шаткий сегодня утром, поэтому я не совсем понимаю, что вы пытаетесь сказать, но если речь идет о более чем одном способе вычисления эллиптического фильтра, я бы предложил найти книгу из Lutovac в эллиптическом википедии. Фильтровать заметки (также Dimopoulos), это довольно сенсационно: у вас может быть 7 способов создать эллиптический фильтр. Если это не то, что вы имели в виду, пожалуйста, игнорируйте мой комментарий.
заинтересованный гражданин

2
Все фильтры Лернера имеют свои полюса на линии, параллельной воображаемой оси. У них есть преимущество наличия приблизительно линейного фазового отклика.
Мэтт Л.

2
Полный фильтр; но если полюса всех параллельных секций лежат на одной линии, то и весь фильтр будет иметь все свои полюсы на этой линии. Вы правы насчет ссылки. Есть та техническая записка от Rader и Gold, на которую я обычно ссылаюсь.
Мэтт Л.

1
Хорошо, в какой журнал мы пойдем? : D Есть ли в этом руководящий принцип? Например, вы ищете возможный параметр, который в некотором аспекте будет лучше, чем эллиптический? (например, переходная полоса против пульсации). Другая семья, которая может быть «интересной», - это * циклоиды ... Но без «принципа упорядочения» мы не можем назвать «худший, плохой, хороший, лучший» любой из них :)
A_A

2
Тема комментариев слишком длинная. Однако, просто добавив параметрический место для вейвлет-фильтров Daubechies ams.org/journals/proc/1996-124-12/S0002-9939-96-03557-5/…|4y(1y)|=1
Laurent Duval

Ответы:


6

В ответе я буду использовать математические обозначения, то есть математический эквивалент выражения амплитудного отклика фильтра в частотной области. Для этого вместо j ω будет использоваться , чтобы лучше отразить вопрос @ Олли о поиске математической параметрической кривой для приближенных фильтров. Поскольку это не конструкция фильтра, угловая частота нормализуется до единицы, следовательно, x вместо ω / ω p .xjωxω/ωp


Я не уверен, что это ответ, который вы ищете, но любой фильтр может быть представлен через общую функцию передачи:

H2(x)=11+ϵp2R2(x)

где , аR(x)- характеристическая функция ослабления. Ap- это ослабление / пульсация в полосе пропускания в дБ, но оно также может быть в полосе задержания для Кауэра / Эллиптика, обратного Паскаля или обратного Чебышева (он же «Чебышевский тип II»). Последние выражаются как:ϵp=10Ap/101R(x)Ap

H2(x)=11+1ϵs2TN2(x)

Для Баттерворта, как вы видели:

R(x)=xN

для Чебышева это , или полиномы Чебышева ( cos / a c o s для x 1 и cosh / a c o s h для x > 1 ), для Elliptic это:R(x)=TN(x)cosacosx1coshacoshx>1

R(x)=cd(NK1Kcd1(x,k),k1)

В книге из Lutovac есть несколько чрезвычайно упрощенных представлений через точные эквивалентные функции для эллиптических фильтров. Например, передаточная функция 2-го порядка может быть точно представлена ​​через:

R(x)=(1k2+1)x21(1k21)x2+1

где единственная зависимость от модуля .k

Это известные типы, для менее известных типов, например, Legendre, , где P N ( x ) - многочлены Лежандра, для фильтров Pascal есть сдвинутая и нормализованная версия Pascal. полиномы, а это:R(x)=PN(x)PN(x)

(N+12x+N12N)

Список можно продолжить. Некоторые из них аппроксимируются по-разному, например, Гауссиан это , который расширяется с помощью ряда Маклаурина, примерно то же самое для Бесселя, который расширяется из выражения Лапласа exp ( - s ) в его знаменательные члены в виде:|H(x)|2=exp(x2)exp(s)

ai=(2N1)!2Nii!(Ni)!

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

R(x2)=i=12x21(i=0kaiPi(x))2

где - это N ( N - 1 ) / 2 a , а a i - некоторые искусно выбранные члены, в зависимости от того , являются ли N или k оба нечетными / четными.k(N1)/2aiNk

Как уже отмечалось, все они не используют частотную область для представления, поскольку в это математическое x , действительное, а не мнимое j ω . Найти корни можно либо путем простого нахождения полюсов (и нулей) передаточной функции при замене x на j ω ., Таким образом выясняя H ( s ) H ( - s ) и выбирая полином Гурвица, либо просто найти корни математического выражения в хxxjωxjωH(s)H(s)x(см. ссылку во втором комментарии ниже). Это приведет к повороту корней на 90 градусов, что означает, что все, что нужно сделать, это переключить реальные и воображаемые части между собой, а затем выбрать правую сторону.

Этот ответ близок к тому, что вы искали?


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

Например, фильтры Баттерворта, работающие примерно с повышением качества, стали причиной того, что был необходим фильтр, который был бы прост в разработке, с монотонно увеличивающимся затуханием. Линквитц-Райли - не что иное, как замаскированный Баттерворт (хитроумный), который суммирует низкие и высокие частоты с одинаковой угловой частотой, что дает плоский ответ, полезный для аудио приложений.

Чебышев (I и II) был спроектирован так, чтобы иметь лучшее затухание за счет ряби в полосе пропускания или полосе останова. Legendre, ultraspherical, Pascal (и, возможно, другие) минимизируют пульсации, тем самым улучшая групповую задержку, за счет слегка уменьшенного ослабления.

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

Фильтры Кауэра / Эллиптика используют пульсации как в полосе пропускания, так и в полосе задерживания, чтобы минимизировать требуемый порядок для того же или лучшего ослабления.

Все они находятся в частотной области, что большинство фильтров. С другой стороны, фильтры Бесселя оказались из-за необходимости аппроксимировать аналоговую задержку, поэтому они сходятся к при увеличении порядка, в то время как фильтры Гаусса были созданы для нулевого выброса, поэтому они приближаются к exp ( - х 2 ) с увеличением порядка.exp(jω)exp(x2)

Конечно, как кто-то предложил, вы также можете посыпать полюса и посмотреть, что получится, возможно, настроить их как звезду или какой-нибудь узор с сотами, выбрать свой любимый лемнискат, но это не тот способ, если вам нужен фильтр из этого. Конечно, вы можете получить экзотический ответ, который может даже быть применимым, кто знает, где, как один случай из миллиона, но на самом деле это только частный случай. Для этого нужно сначала навязать цель проектирования и посмотреть, как ее можно достичь с помощью физически реализуемого фильтра. Даже если это означает, что нужно придумать фильтр «кто знает где». :-)


Учитывая недавний ответ @Olli, рассмотрим простой случай фильтра Баттерворта, предназначенного, скажем, для 0.9@fp=1, 0.1@fs=5. Расчеты примерно такие:

Ap=20log10(0.9)=0.91515 dBAs=20log10(0.1)=20 dBϵp=10Ap/101=0.48432ϵs=10As/101=9.94987F=fsfp=51=5N=logϵsϵplogF=1.878

N is calculated as rounded up, so N=2. This means that, if you match the filter's response to the passband, you'll get a higher attenuation in the stopband @fs. Using the first formula up, the attenuation@fs is:

H(fs)=11+0.48432252N=0.08231<0.1

If you'd have to match the stopband to have 0.1@fs, you'd have to apply a frequency correction:

ωscale=(ϵsϵp)1/Nfpfs=9.949870.5=0.9065H(5ωscale)=0.1

So ωscale can vary from 1 to 0.9065 and you'll get all the infinite possibilities in between the two extremes. Can you do it? Yes. Is it worth it? Even if you might find an argument or two, the general answer is still no. How was all this possible? Because the initial response of the Butterworth filter was already obtained, so you knew beforehand that you had an analytical expression for a filter that has monotonically decreasing frequency attenuation, which lead to finding out the poles from the denominator of the transfer function, which happen to lie on a circle with equal angles.


Given the recent answer from @Olli, there are a few things that need spelling out. First, all this is about filter design, no matter how you look at it: from a mathematical or from a physical realizability point of view.

If it is mathematical, then there is some interesting part about the theory of it, namely obtaining a different order from the same filter without the need for re-designing the original filter.

But from a physical realizability point of view, the whole process implies some extra, unneeded work, that (should) lead to the same result, and that is precisely the part about the increasing/decreasing the filter's order to obtain a new one. My arguments are as follows.

Any filter, at its core, serves to filter unneeded frequencies, be they electrical, or mechanical, or other physical quantities. Their purpouse is to modify a spectrum (or group delay, or time response). If there is the need for such a device, then that device cannot be designed by simply throwing in a filter of any kind, "just put it there, it'll filter out stuff"; its design is, most often, quite involved. But all this process has to start from the requirements. That is, first there has to be a specific goal, "let's filter out everything above 100 Hz", or "let only the infrared light pass through", or anything similar, which starts by first determining the parameters with which that filter has to work.

As a quick example, if there was a need to filter out frequencies below 300 Hz and above 3000 Hz, one wouldn't just throw in any bandpass filter with those corner frequencies, attenuations must be also specified, whether ripple in the passband, or stopband, or both, is needed or accepted, whether the phase is linear or not, how will the group delay affect all this, etc. So, first of all, there are specific parameters by which the filter needs designing.

Once the parameters are specified, how will the filter be designed? Let's presume that there is a need for a 12th order elliptic lowpass filter, and that there is a possibility to increase a low order filter to a high order one (see @Olli's answer). Let's say that the process of transforming a 4th order into a 12th order is a flawless one, that there is a way to specify the design parameters for the 4th order filter in such a way that, after transforming, the resulting 12th order would end up satisfying those conditions. "Premeditated thinking", if you will.

The question that comes is this: how will the 4th order filter be designed? The answer can only be through the known ways of designing it. And, if there are other methods, to come, or yet to be invented, those would have to be applied, first, in order to design that 4th order filter. Only afterwards the 12th order can be calculated. As assumed from the beginning, even with a flawless transformation process it would only mean that the resulting filter, the 12th order, towards which the whole design tries to converge, needs two steps of design: one, for the 4th order, and the second, for the 12th order, making the whole process an unnecessarily encumbered one, since the 12th order filter could have simply been designed, in the first place, with the method used for the 4th order.

Let's go a bit further and assume some more. The resulting poles of the 12th order would lie on an ellipse, and the zeroes on the imaginary axis. The distances between them would be precisely defined by the underlying elliptic functions that govern the elliptic filters. Suppose there is a way to define those curves, as @Olli hopes, in such a manner that it is possible to readily design a filter from the beginning, in one shot, by simply using these (parametric or not) curves by which all the pole placement is done. So far, so good. But those curves would have to first be calculated, and the parameters by which they unravel are the exact ones that are used for the filter design, the same ones that would generate the filter through other methods, known or yet unknown. What's more, the calculations are still left to be done, and, most probably, the underlying definitions for those parametric curves would have to be elliptical, one way or another, or no elliptical filter would come out of it[note#1]. Which means that the whole process would simply be yet another method of design for the elliptic filters, since the poles of the elliptical filter have closed form expressions, already.

Don't get me wrong. If one filter can be designed one way, the same way it can be designed in another. It's just one of those "yet to be known" ways. Bravo to the inventor. But if this method of design implies extra steps in order to converge to the same results it would take for a different method, then it doesn't seem like a feasible approach. And please note: I am not using names or descriptive labels when I am talking about the filter designs, just generic names, because it doesn't really matter which method you're using as long as the results are correct and the method isn't encumbering for the design process.

[note#1]: Simply following a generic curve in order to place the poles is not enough, and I'll give two examples, related to the Butterworth filters, who have the poles placed on a circle with equidistant angles. Chebyshev type I filters have the poles placed on an ellipse, with the angles of the Butterworth, but projected on the imaginary axis until they intercept the ellipse. Modifying the distance between the poles will result in a non-equiripple behaviour, rendering the filter a non-Chebyshev type. Similarly, the poles of the minimum-Q elliptic filter are disposed on an underlying circle, but that doesn't mean it's a Butterworth (even if the ripple is the minimum possible for an elliptic filter), because it has unequal distances between the angles. For the last one, here's a comparison of two 8th order Butterworth and minimum-Q elliptic:

Butterworth vs min-Q elliptic

Overall, despite the genuine interest the question brings, I fear it has no more than a theoretical value, at best an educational one, since it doesn't manage to fit the very part dealing with the filter design. Of course, if it should prove to be of actual value, I'd be glad to be proven wrong, as it would mean that there is a new method of filter design, possibly better than the already existent ones.


@OlliNiemitalo Yes, it's the non-squared version. Do what the priest says, not what he does. :-) Ap is the passband attenuation/ripple, in dB, but it can also be for the stopband, in the case of Cauer/Elliptic, inverse Chebyshev, or inverse Pascal. I see there are other minor mistakes, I'll edit them.
a concerned citizen

1
Olli, there are nice closed-form expressions for both Tchebyshevs and the Butterworth. but not so much for the Elliptical/Cauer filter. getting a well-defined alg down for that (the loci of poles and zeros) is (how shall we say?) a copulating female canine.
robert bristow-johnson

1
±j/(ksn(iK/N,k)),i=1,2,.. (different odd/even), but that requires using theta functions and whatnot, which gets very "fluffy" in terms of CPU. Then there's Lutovac, who, even if he can't use prime numbers, greatly simplifies them, but they get bigger as the order increases.
a concerned citizen

1
@robertbristow-johnson Me neither, as mentioned at the end of the original edit, and in one of the comments, but it looks like it got edited along the way, I'll correct it. As for the elliptic functions, Burrus and another one (forgot the name, Paarman?) use the sn(K+sn1()) version, but sn(K+x)=cd(x), the shifted Jacobi sine, a fact noted by Lutovac. So, to avoid the need to calculate an extra complete elliptic integral, one can write cd(), there's no difference. A simple plot can show it (k1=ϵp/ϵs,k=fp/fs,K1=K(k1),K=K(k)).
a concerned citizen

1
@robertbristow-johnson You missed the part where I say that all the expressions use x as a variable, because they reflect the mathematical function that describes the filter response, since it's related to the mathematical approach of Olli's. Plotting all the functions with x in any mathematical software will get you the magnitude, without going into frequency domain. I left outside replacing x=jω, making H(s)H(s), and selecting only the Hurwitz criterion poles/zeroes, that is for filter design. Besides, you can get the poles without that, just as well (see link in comment#2).
a concerned citizen

2

While I intuitively feel that I understand what is required, I struggle to express it. I am not sure if this is because of my own limitations or if indeed the problem is difficult or ill-posed. I have a feeling that it is ill-posed. So, here is my attempt:

  1. The objective is to build a filter. That is, calculate a set of coefficients of some rational form:

H(s)=B(s)A(s)=m=0MbmsmsN+n=0N1ansn

(Please note, it doesn't have to be over the s-plane, it could be over the z-plane too. And also, simpler forms of it could be considered (e.g. H(s) to have only poles). Let's run with the s-plane for the moment and let's keep the nominator in too).

  1. Digital filters are characterised by their frequency and phase responses, both of which can be completely determined by the values (or, positions on the s-plane) of their an,bm coefficients. The discussion so far seems to be focusing on the frequency response so let's consider that one for the moment.

  2. Given a set of some an,bm and some point σ+jω on the s-plane, the geometric way of deriving the frequency response at that point is to form "zero vectors" (from the locations of the zeros, towards the specific point) and "pole vectors" (similarly for the poles), sum their magnitudes and form the ratio as in the equation above.

  3. To ask "What [...] filter types defined by some optimality criterion have infinite subsets defined by parametric curves [...]" is to ask "What is the pair of some parametric curves A(s,Θ),B(s,Θ) whose locations also result in a magnitude response curve with specific desired characteristics over Θ (e.g. slope, ripple, other). Where Θ is the parameter(s) of the...parametric.

  4. A note, at this point: On the one hand, we are looking for A(s),B(s) that satisfy two constraints. First of all they have to satisfy the constraints of the parametric (easy) and secondly they have to satisfy the constraints specified by the magnitude response characteristic (difficult).

  5. I think that the problem, in its current form, is ill-posed because there is no analytic way to connect the frequency response constraints with the parametrics A(s,Θ),B(s,Θ), except the direct evaluation of it. In other words, it is impossible at the moment to specify some constraints on the frequency response curve and through that, work backwards and find those parametrics that satisfy these constraints. We can go the other way around, but not backwards.

  6. Therefore, what (i think that) realistically can be done, at the moment, is to accept A(s,Θ),B(s,Θ) of some specific form and then, either check how do they fare as filters OR, iteratively move their coefficients around as much as their parametric allow, to squeeze the best performance they can offer out of a particular range of their Θ. However, we might find that given the worked out characteristics of elliptics (for example), a given iterative scheme on a parametric might choose to "bend" the coefficients as close as possible to some "elliptic" region characteristic. This is why earlier on, I mention that we might find that a complex parametric might be possible to be broken down to a "sum of elliptics" or a "sum of curves with known characteristics". Perhaps a third constraint is required here, reading "Stay away from known configurations of A(s),B(s)", in other words, penalise solutions that start looking like elliptics (but still in an iterative scheme).

Finally, if this path is not too wrong so far then we are somewhere close to something like Genetic Algorithms For Filter Design, or some other informed "shoot in the dark" technique by which the coefficients of a filter satisfying specific criteria might be derived with. The above is just an example, there are more publications along these lines out there.

Hope this helps.


+1 I like your program. For your point #4 and others, the optimization goal could be stated in terms of limN(H(iω))1/N, or usually its absolute value. Then again it would mean we are already relying on the the viability of the approach, which is in question. So it would be necessary to also check with some finite N filters. In point #7, I don't think "repulsion of elliptics" would help as it would give sub-optimal near-elliptic filters. Rather, the optimization goal should be changed.
Olli Niemitalo

1
Thank you. I agree that the optimisation goal is crucial here. "Repulsion of the eliptics" should be used more often... :)
A_A

2

i don't think it's particularly remarkable that Butterworth filters, defined as all-pole filters that are maximally flat at ω=0 (for LPF prototype, meaning the most possible derivatives of |H(jω)| are zero at ω=0), have s-plane poles that lie equally spaced on the left half-circle of radius ω0.

from the "maximally flat" and "no zeros", you can derive

|H(jω)|2=11+(ωω0)2N

for the Nth-order Butterworth.

so

|H(s)|2=11+(sjω0)2N

s=pn is a pole when the denominator is zero.

1+(pnjω0)2N=0

or

(pnjω0)2N=1

pn2N=(jω0)2N

|pn|=ω0

2Narg{pn}=π+2Nπ2+2πn

arg{pn}=π2+πN(n12)

for Nth-order Tchebyshev (Type 1, which is all-pole), it's like this:

|H(jω)|2=11+ϵ2TN2(ωωc)

where

TN(x){cos(Narccos(x)),if |x|1cosh(Narccosh(x)),if x1(1)Ncosh(Narccosh(x)),if x1

are the Nth-order Tchebyshev polynomials and satisfy the recursion:

T0(x)=1T1(x)=xTn+1(x)=2xTn(x)Tn1(x)nZ1

and ωc is the "passband cutoff" frequency and not to be confused with the -3 dB frequency ω0. (but the two are related.)

the passband ripple parameter is ϵ=10dBripple101

analytic extension again:

|H(s)|2=11+ϵ2TN2(sjωc)

and again s=pn is a pole when the denominator is zero.

1+ϵ2TN2(pnjωc)=0

or

TN(pnjωc)=±jϵ

(because cos(θ)=cosh(jθ) we can use either cos() or cosh() expression for TN()

cosh(Narccosh(pnjωc))=±jϵ

Narccosh(pnjωc)=arccosh(±jϵ)

since

y=cosh(x)=12(ex+ex)
and
x=arccosh(y)=log(y±y21)

then

Nlog(pnjωc±(pnjωc)21)=log(±jϵ±(±jϵ)21)

Nlog((pn)+j(pn)jωc±((pn)+j(pn)jωc)21)=log(±j(1ϵ±1ϵ2+1))

Nlog(j(pn)+(pn)ωc±(j(pn)+(pn)ωc)21)=log(±j(1ϵ±1ϵ2+1))

oh dear i might not get this blasted out in 12 hours

i've decided that i am too lazy to grok through this. if anyone wants to pick it up, feel free to. lotsa conversion between rectangular and polar notation of complex values. remember when

w=± z 
then
|w|=+|z|
and
arg{w}=12arg{z}+arg{±1}=12arg{z}+π2(1±1)

and remember

log(z)=log|z|+jarg{z}+j2πnnZ

you may add any integer multiple of 2π (say "2πn") to any arg{} (choose the right-hand log() which is how you can get different poles for pn).

if you like mathematical masturbation with complex variables, knock yourself out.


+1 for the interesting observation, but since this doesn't address the questions I hope there will be other candidates for the bounty.
Olli Niemitalo

so Olli, you can see how the derivation of the poles for Tchebyshev 1 and poles/zeros for Tchebyshev 2 is similarly done?
robert bristow-johnson

the Jabobi Elliptical is a bitch. i dunno how to evaluate it without looking it up in Antonio. and it ain't gonna be closed form.
robert bristow-johnson

Yes, the zeros of Tchebyshev 2 are uniformly distributed on parametric curve f(α)=j/cos(πα) for cutoff 1.
Olli Niemitalo

and how do you get that result and the loci of the poles for either Tchebyshev 1 or 2?
robert bristow-johnson

0

12th order elliptic to 4th order elliptic

(I'm not eligible to the bounty.) I tried to produce a counterexample to question 3 in Octave but was pleasantly surprised that I couldn't. If the answer to the question 3 is yes, then according to Fig 5. of the question, specific poles and zeros should be shared between an elliptic filter of order 4 and an elliptic filter of order 12, here shown explicitly: Shared poles and zeros
Figure 1. Poles and zeros potentially shared between elliptic filters of order N=12 and N=4, in blue and numbered in order of ascending parameter α of a parametric curve f(α).

Let's design an order 12 elliptic filter with some arbitrary parameters: 1 dB pass band ripple, -90 dB stop band ripple, cutoff frequency 0.1234, s-plane rather than z-plane:

pkg load signal;
[b12, a12] = ellip (12, 0.1, 90, 0.1234, "s");
ra12 = roots(a12);
rb12 = roots(b12);
freqs(b12, a12, [0:10000]/10000);

12th order filter magnitude frequency response
Figure 2. The magnitude frequency response of the 12th order elliptic filter designed using ellip.

scatter(vertcat(real(ra12), real(rb12)), vertcat(imag(ra12), imag(rb12)));

Poles and zeros, filter order 12
Figure 3. Poles (red) and zeros (blue) of order 12 elliptic filter designed using ellip. Horizontal axis: real part, vertical axis: imaginary part.

Let's construct an order 4 filter by reusing select poles and zeros of the order 12 filter, per Fig. 1. In the particular case, ordering the poles and zeros by the imaginary part is sufficient:

[~, ira12] = sort(imag(ra12));
[~, irb12] = sort(imag(rb12));
ra4 = [ra12(ira12)(2), ra12(ira12)(5), ra12(ira12)(8), ra12(ira12)(11)];
rb4 = [rb12(irb12)(2), rb12(irb12)(5), rb12(irb12)(8), rb12(irb12)(11)];
freqs(poly(rb4), poly(ra4), [0:10000]/10000);

Fourth order filter magnitude frequency response
Figure 4. Magnitude frequency response of the 4th order filter that has all poles and zeros identical to certain ones of those of the 12th order filter, per Fig. 1. Zooming in gives a characterization of the filter: 3.14 dB pass band equiripple, -27.69 dB stop band equiripple, cutoff frequency 0.1234.

It is my understanding that an equiripple pass band and an equiripple stop band with as many ripples as the number of poles and zeros allows is a sufficient condition to say that the filter is elliptic. But let's try if this is confirmed by designing an order 4 elliptic filter by ellip with the characterization obtained from Fig 3 and by comparing the poles and zeros between the two order 4 filters:

[b4el, a4el] = ellip (4, 3.14, 27.69, 0.1234, "s");
rb4el = roots(b4el);
ra4el = roots(a4el);
scatter(vertcat(real(ra4), real(rb4)), vertcat(imag(ra4), imag(rb4)));

That against:

scatter(vertcat(real(ra4el), real(rb4el)), vertcat(imag(ra4el), imag(rb4el)), "blue", "x");

4th order filter pole/zero comparison
Figure 5. Comparison of pole (red) and zero (blue) locations between an ellip-designed 4th order filter (crosses) and a 4th order filter (circles) that shares certain pole and zero locations with the 12th order filter. Horizontal axis: real part, vertical axis: imaginary part.

The poles and zeros coincide between the two filters to three decimal places, which was the precision of the characterization of the filter derived from the order 12 filter. The conclusion is that at least in this particular case both the poles and zeros of the order 4 elliptic filter and those of the order 12 elliptic filter could have been obtained, at least up to a precision, by uniformly distributing them on the same parametric curves. The filters were not Butterworth or Chebyshev I or II type filters as both the pass band and the stop band had ripples.

4th order elliptic to 12th order elliptic

Conversely, can the poles and zeros of the 12th order filter be approximated from a pair of continuous functions fitted to the poles and zeros of the 4th order ellip filter?

If we duplicate the four poles (Fig. 5) and flip the sign of the real parts of the duplicates, we get an oval of sorts. As we go round and round the oval, the pole locations that we pass give a periodic discrete sequence. It is a good candidate for periodic band-limited interpolation by zero-padding its discrete Fourier transform (DFT). Of the resulting 24 poles the ones with a positive real part are discarded, halving the number of poles to 12. Instead of the zeros, their reciprocals are interpolated, but otherwise the interpolation is done the same way as with the poles. We start with the same ellip-designed 4th order filter as earlier (approximately identical to Fig. 4):

pkg load signal;
[b4el, a4el] = ellip (4, 3.14, 27.69, 0.1234, "s");
rb4el = roots(b4el);
ra4el = roots(a4el);
rb4eli = 1./rb4el;
[~, ira4el] = sort(imag(ra4el));
[~, irb4eli] = sort(imag(rb4eli));
ra4eld = vertcat(ra4el(ira4el), -ra4el(ira4el));
rb4elid = vertcat(rb4eli(irb4eli), -rb4eli(irb4eli));
ra12syn = -interpft(ra4eld, 24)(12:23);
rb12syn = -1./interpft(rb4elid, 24)(12:23);
freqs(poly(rb12syn), poly(ra12syn), [0:10000]/10000);

Magnitude frequency response of the 4->12th order interpolated filter
Figure 6. Magnitude frequency response of a 12th order filter with the poles and zeros sampled from curves matched to those of the 4th order filter.

It is not an accurate enough of a mockup of the Fig. 2 response to be useful. The stop band fares pretty well but the pass band is tilted. The band edge frequencies are approximately correct. Still, this shows potential considering the parametric curves were only described by 4 degrees of freedom each.

Let's have a look at how the poles and zeros match those of the N=12 ellip-generated filter:

[b12, a12] = ellip (12, 0.1, 90, 0.1234, "s");
ra12 = roots(a12);
rb12 = roots(b12);
scatter(vertcat(real(ra12), real(rb12)), vertcat(imag(ra12), imag(rb12)), "blue", "x");
scatter(vertcat(real(ra12syn), real(rb12syn)), vertcat(imag(ra12syn), imag(rb12syn)));

Comparison of poles and zeros for N=12
Figure 7. Comparison of pole (red) and zero (blue) locations between an ellip-designed 12th order filter (crosses) and a 12th order filter (circles) that was derived from the 4th order filter. Horizontal axis: real part, vertical axis: imaginary part.

The interpolated poles are quite a bit off, but zeros are matched relatively well. A larger N as the starting point should be investigated.

6th order elliptic to 18th order elliptic

Doing the same as above but starting at 6th order and interpolating to 18th order shows a seemingly well-behaved magnitude frequency response, but still has trouble in the pass band when examined closely:

[b6el, a6el] = ellip (6, 0.03, 30, 0.1234, "s");
rb6el = roots(b6el);
ra6el = roots(a6el);
rb6eli = 1./rb6el;
[~, ira6el] = sort(imag(ra6el));
[~, irb6eli] = sort(imag(rb6eli));
ra6eld = vertcat(ra6el(ira6el), -ra6el(ira6el));
rb6elid = vertcat(rb6eli(irb6eli), -rb6eli(irb6eli));
ra18syn = -interpft(ra6eld, 36)(18:35);
rb18syn = -1./interpft(rb6elid, 36)(18:35);
freqs(poly(rb18syn), poly(ra18syn), [0:10000]/10000);

6th order <code>ellip</code>-generated filter
18th order filter derived from the
Figure 8. Top) 6th order ellip-generated filter, Bottom) 18th order filter derived from the 6th order filter. Zoomed in, the pass band has only two maxima and about 1 dB of ripple. The stop band is nearly equiripple with 2.5 dB of variation.

My guess about the trouble at the pass band is that the band-limited interpolation isn't working well enough with the (real parts of the) poles.

Exact curves for elliptic filters

It turns out that elliptic filters for which NNz=NNp=N provide positive examples to questions 1 and 2. C. Sidney Burrus, Digital Signal Processing and Digital Filter Design (Draft). OpenStax CNX. Nov 18, 2012 gives the zeros and poles of the transfer function of a sufficiently general NNz=NNp=N elliptic filter in terms of the Jacobi elliptic sine sn(t,k). Noting that sn(t,k)=sn(t,k), Burrus Eq. 3.136 can be rewritten for zeros szi, i=1N as:

(1)szi=jksn(K+K(2i+1)/N,k),

where K is a quarter period of sn(t,k) for real t, and 0k1 can be seen as a degree of freedom in the parameterization of the filter. It controls the transition band width relative to pass band width. Recognizing (2i+1)/N=2α (see Eq. 2 of the question) where α is the parameter of the parametric curve:

(2)fz(α)=jksn(K+2Kα,k),

Burrus Eq. 3.146 gives the upper-left quarter-plane poles including a real pole for odd N. It can be rewritten for all poles spi, i=1N with any N as:

(3)spi=cn(K+K(2i+1)/N,k)dn(K+K(2i+1)/N,k)sn(ν0,1k2)×cn(ν0,1k2)+jsn(K+K(2i+1)/N,k)dn(ν0,1k2)1dn2(K+K(2i+1)/N,k)sn2(ν0,1k2),

where dn(t,k)=1k2sn2(t,k) is one of the Jacobi elliptic functions. Some sources have k2 as the second argument for all of these functions and call it the modulus. We have k and call it the modulus. The variable 0<ν0<K´ can be thought of as one of the two degrees of freedom (k,ν0) of the sufficiently general parametric curves, and one of the three degrees of freedom (k,ν0,N) of a sufficiently general elliptic filter. At ν0=0 the pass band ripple would be infinite and at ν0=K´ where K´ is the quarter period of Jacobi elliptic functions with modulus 1k2, poles would equal zeros. By sufficiently general I mean that there is just one remaining degree of freedom that controls the pass band edge frequency and which will manifest itself as uniform scaling of both parametric curve functions by the same factor. The subset of elliptic filters that share fp(α), fz(α), and an irreducible fraction Nz/Pz=1, are transformed to another subset of infinite size in dimension N upon change of the trivial degree of freedom.

By the same substitution as with the zeros, the parametric curve for the poles can be written as:

(4)fp(α)=cn(K+2Kα,k)dn(K+2Kα,k)sn(ν0,1k2)×cn(ν0,1k2)+jsn(K+2Kα,k)dn(ν0,1k2)1dn2(K+2Kα,k)sn2(ν0,1k2).

Let's plot the functions and the curves in Octave, for values of k and ν0 (v0in the code) copied from Burrus Example 3.4:

k = 0.769231; 
v0 = 0.6059485; #Maximum is ellipke(1-k^2)
K = 1024; #Resolution of plots
[snv0, cnv0, dnv0] = ellipj(v0, 1-k^2);
dnv0=sqrt(1-(1-k^2)*snv0.^2); # Fix for Octave bug #43344
[sn, cn, dn] = ellipj([0:4*K-1]*ellipke(k^2)/K, k^2);
dn=sqrt(1-k^2*sn.^2); # Fix for Octave bug #43344
a2K = [0:4*K-1];
a2KpK = mod(K + a2K - 1, 4*K)+1;
fza = i./(k*sn(a2KpK));
fpa = (cn(a2KpK).*dn(a2KpK)*snv0*cnv0 + i*sn(a2KpK)*dnv0)./(1-dn(a2KpK).^2*snv0.^2);
plot(a2K/K/2, real(fza), a2K/K/2, imag(fza), a2K/K/2, real(fpa), a2K/K/2, imag(fpa));
ylim([-2,2]);
a = [1/6, 3/6, 5/6];
ai = round(a*2*K)+1;
scatter(vertcat(a, a), vertcat(real(fza(ai)), imag(fza(ai)))); ylim([-2,2]); xlim([0, 2]);
scatter(vertcat(a, a), vertcat(real(fpa(ai)), imag(fpa(ai))), "red", "x"); ylim([-2,2]); xlim([0, 2]);

Analytic extensions of parametric curve functions for Burrus Example 3.4
Figure 9. fz(α) and fp(α) for Burrus Example 3.4, analytically extended to period α=02. The three poles (red crosses) and the three zeros (blue circles, one infinite and not shown) of the example are sampled uniformly with respect to α at α=1/6, α=3/6, and α=5/6, from these functions, per Eq. 2 of the question. With the extension, the reciprocal of Im(fz(α)) (not shown) oscillates very gently, making it easy to approximate by a truncated Fourier series as in the previous sections. The other periodic extended functions are also smooth, but not so easy to approximate that way.

plot(real(fpa)([1:2*K+1]), imag(fpa)([1:2*K+1]), real(fza)([1:2*K+1]), imag(fza)([1:2*K+1]));
xlim([-2, 2]);
ylim([-2, 2]);
scatter(real(fza(ai)), imag(fza(ai))); ylim([-2,2]); xlim([-2, 2]);
scatter(real(fpa(ai)), imag(fpa(ai)), "red", "x"); ylim([-2,2]); xlim([-2, 2]);

Parametric curves for Burrus Example 3.4
Figure 10. Parametric curves for Burrus Example 3.4. Horizontal axis: real part, vertical axis: imaginary part. This view does not show the speed of the parametric curve so the three poles (red crosses) and the three zeros (blue circles, one infinite and not shown) do not appear to be uniformly distributed on the curves, even as they are, with respect to the parameter α of the parametric curves.

Elliptic filter design by the exact pole and zero formulas given by Burrus is fully equivalent to sampling from the exact fp(α) and fz(α), so methods are equivalent and available. Question 1 remains open-ended. It may be that other types of filters have infinite subsets defined by fp(α) and fz(α) and Nz/Np. Of methods of approximating the elliptic parametric curves, those that do not depend on the exact functional form may be transferable to other filter types, I think most likely to those that generalize elliptic filters, such as some subset of general equiripple filters. For them, exact formulas for poles and zeros may be unknown or intractable.

Going back to Eq. 2, for odd N, we have for one of the zeros α=0.5, which sends it to infinity by sn(2K,k)=0. No such thing takes place with the poles (Eq. 4). I have updated the question to have such zeros (and poles, in case) included in the count NNz (or NNp). At k=0, all zeros go to infinity according to fz(α), which looks to give type I Chebyshev filters.

I think question 3 just got resolved and the answer is "yes". That, as it appears that we can cover all cases of elliptic filter without being in conflict with NNz=NNp, with the new definition of those.


Olli, you can't give yourself the bounty anyway. your 500 points are gone forever. just don't waste them like i did accidentally once at the EE.SE page.
robert bristow-johnson

Comments are not for extended discussion; this conversation has been moved to chat.
jojek

1
Yes, they still are, that is the special case for odd orders, when there's an additional, single, real pole, re/(s+re), to the transfer function. As for the rational function starting from zeroes, only, you have:
R(x)=in/2x2zeroi2jn/2x2k/zeroj2
, where k=fs/fp. For odd orders, R(x)=R(x)x. This will make the filter have unnormalized gain, so it should be scaled by R(0). Poles come from expanding 1+ϵ2R2(x) and finding the roots of the denominator, then selecting the left-hand side, and forming the transfer function.
a concerned citizen

I wasn't sure if I said this. To make the transfer function, it's not really necessary to follow the book by making H(s)H(s), then left-hand side poles, then rational transfer function according to @A_A's formula. Mathematically, and the practical result, is that after finding the roots from 1+ϵ2R2(x) (note: x, not jω, or s), simply select the roots with the positive realparts and either positive or negative imagparts (not both). I.e. for N=4, there would be 4 pairs/8 poles; after selection you have 2 different poles. Then simply:
N(s)=iN/2|pi|2
...
a concerned citizen

(for all-pole filters), where p=σ+jω, and
N(s)=iN/2s2+|zi|2
, where z=jμ (for pole-zero filters), while the denominator:
D(s)=jN/2s2+2Re(pj)s+|pj|2
and
H(s)=N(s)D(s)
. This would be the lowpass prototype.
a concerned citizen

0

It seems that most of the participants in this discussion do not know a type of filter which may be their real solution ! Namely the Paynter filters developed by Henry M.Paynter who was a professor at MIT and partner of Philbrick Reseach. They are the best approach to "running" average filtering and treating non deterministic input signals, far better than Bessel-Thomson. I used them for physiological-medical and sonar applications. Their theories are in the January-July and July-October editions of the "Lightning Empiricist" under the general title: "New approaches for the design of Active Low Pass Filters" by Peter D. Hansen Tables are given for the poles of the 2nd, 4th and 6th order filters. I computed the same for the 8th order.


And it would seem you missed OP's point: to find the Holy Graal of mathematical formulas that can be used to calculate any filter type (or similar). :-)
a concerned citizen

0

I'll add here some notes that may be useful if someone wants to calculate the limit N of the Nth root of magnitude of a transfer function with a multiple of N poles and zeros distributed on arbitrary parametric curves. One could approximate that by using a large N and by distributing the poles and zeros uniformly over the parameter of the parametric curve. Unfortunately the approximation always has infinite error on dB scale at the locations of the poles and zeros of the realizable transfer function. In that sense a better building block is a line segment with uniform pole or zero distribution along its length. Considering just N zeros, distributed on a line segment with start point x0+y0i and end point x1+y1i:

limN|H(0)|1/N=01|(x0+y0i)(1α)+(x1+y1i)α|dα=01((x0(1α)+x1x)2+(y0(1α)+y1α)2)dα=e01log((x0(1α)+x1α)2+(y0(1α)+y1α)2)dα=e((x0y1x1y0)atan2(x0y1x1y0,x0x1+y0y1)(x0x1)2+(y0y1)21)×(x02+y02)(x1(x0x1)+y0(y0y1)+(x0x1)22((x0x1)2+(y0y1)2))×(x12+y12)(x0(x1x0)+y1(y1y0)+(x1x0)22((x1x0)2+(y1y0)2))

Some special cases need to be handled separately. If x0=0 and y0=0 we must use the limit:

=e1x12+y12

Or conversely if x1=0 and y1=0:

=e1x02+y02

Or if the line segment has zero length, x0=x1 and y0=y1, we have just a regular zero:

=x02+y02

To do the evaluation at different argument values of H(z) or H(s), simply subtract that value from the line start and end points.

What this looks like on the complex plane: Magnitude of the transfer function with a single zero
Figure 1. Magnitude of the transfer function with a single zero. 1 dB steps are indicated in turquoise and 10 dB steps in yellow.

The limit N->inf of the Nth root of magnitude of a transfer function with N zeros uniformly distributed on a line segment
Figure 2. The limit N of the Nth root of magnitude of a transfer function with N zeros uniformly distributed on a line segment. There is a crease at the line segment, but the value never goes to zero like with a regular, realizable zero. At sufficient distance this would look like a regular zero. The color code is the same as in Fig. 1.

enter image description here
Figure 3. An approximation of Fig. 2 using discrete zeros: 5th root of the magnitude of a polynomial with 5 zeros distributed uniformly on the line segment. At the location of each zero, the value is zero, because 01/5=0.

Figs. 1 and 2 were generated using this Processing sketch, with source code:

float[] dragPoints;
int dragPoint;
float dragPointBackup0, dragPointBackup1;
boolean dragging, activated;
PFont fnt;
PImage bg;
float pi = 2*acos(0.0);
int appW, appH;
float originX, originY, scale;

int numDragPoints = 2;

void setup() {
  appW = 600;
  appH = 400;
  originX = appW/2;
  originY = appH/2;
  scale = appH*7/16;
  size(600, 400);
  bg = createImage(appW, appH, RGB);
  dragging = false;
  dragPoint = -666;
  dragPoints = new float[numDragPoints*2]; 
  dragPoints[0] = originX-appW*0.125;
  dragPoints[1] = originY+appH*0.125;
  dragPoints[2] = originX+appW*0.125;
  dragPoints[3] = originY-appH*0.125;
  fnt = createFont("Arial",16,true);
  ellipseMode(RADIUS);
  activated = false;
}

void findDragPoint() {
  int cutoff = 49;
  int oldDragPoint = dragPoint;
  float dragPointD = 666666666;
  dragPoint = -666;
  for (int t = 0; t < numDragPoints; t++) {
    float d2 = (mouseX-dragPoints[t*2])*(mouseX-dragPoints[t*2]) + (mouseY-dragPoints[t*2+1])*(mouseY-dragPoints[t*2+1]);
    if (d2 <= dragPointD) {
       dragPointD = d2;
       if (dragPointD < cutoff) {
         dragPoint = t;
       }
    }
  }
  if (dragPoint != oldDragPoint) {
    loop();
  }
}

void mouseMoved() {
  if (activated) {
    if (!dragging) {
      findDragPoint();
      loop();
    }
  }
}

void mouseClicked() {
  if (dragPoint < 0) {
    activated = !activated;
    if (activated) {
      findDragPoint();      
    }
  }
  loop();
}

void mousePressed() {  
  if (dragPoint >= 0) {
    dragging = true;
    dragPointBackup0 = dragPoints[dragPoint*2];
    dragPointBackup1 = dragPoints[dragPoint*2+1];
  } else {
    dragging = false; // Not needed?
  }
  loop();
}

void mouseDragged() {
  if (!activated) {
    dragPoint = -666;
    activated = true;
    findDragPoint();
  }
  if (dragging) {
    int x = mouseX;
    int y = mouseY;
    if (x < 5) {
      x = 5;
    } else if (x >= appW - 5) {
      x = appW - 6;
    }
    if (y < 5) {
      y = 5;
    } else if (y >= appH - 5) {
      y = appH - 6;
    }
    dragPoints[dragPoint*2] = x;
    dragPoints[dragPoint*2+1] = y;
    loop();
  }  
}

void mouseReleased() {
  if (activated && dragging) {
    dragging = false;
    loop();
  }
}

float sign(float value) {
  if (value > 0) {
    return 1.0;
  } else if (value < 0) {
    return -1.0;
  } else {
    return 0;
  }
}

void draw() {
  for(int y = 0; y < appH; y++) {
    for(int x = 0; x < appW; x++) {
      float x0 = (dragPoints[0]-x)/scale;
      float y0 = (dragPoints[1]-y)/scale;
      float x1 = (dragPoints[2]-x)/scale;
      float y1 = (dragPoints[3]-y)/scale;
      float gain;
      if (x0 == x1 && y0 == y1) {
        gain = sqrt(x0*x0 + y0*y0);
      } else if (x0 == 0 && y0 == 0) {
        gain = exp(-1)*sqrt(x1*x1 + y1*y1);
      } else if (x1 == 0 && y1 == 0) {
        gain = exp(-1)*sqrt(x0*x0 + y0*y0);
      } else {
        gain = exp((x0*y1 - x1*y0)*atan2(x0*y1 - x1*y0, x0*x1 + y0*y1)/(sq(x0 - x1) + sq(y0 - y1)) - 1)*pow(x0*x0 + y0*y0, (x1*(x0 - x1) + y0*(y0 - y1) + sq(x0 - x1))/(2*(sq(x0 - x1) + sq(y0 - y1))))*pow(x1*x1 + y1*y1, (x0*(x1 - x0) + y1*(y1 - y0) + sq(x1 - x0))/(2*(sq(x1 - x0) + sq(y1 - y0))));
      }
      int intensity10 = round(log(gain)/log(10)*0x200)&0xff;
      int intensity1 = round(log(gain)/log(10)*(0x200*10))&0xff;
      bg.pixels[y*appW + x] = color(intensity10, 0xff, intensity1);
    }
  }
  image(bg, 0, 0);
  noFill();
  stroke(0, 0, 255);
  strokeWeight(1);
  line(dragPoints[0], dragPoints[1], dragPoints[2], dragPoints[3]);  

  //ellipse(originX, originY, scale, scale);  
  if (!activated) {
    textFont(fnt,16);
    fill(0, 0, 0);
    text("Click to activate",10,20);
    for (int x = 0; x < appW; x++) {
      color c = color(110*x/appW+128, 110*x/appW+128, 110*x/appW+128);
      set(x, 0, c);  
    }
    for (int y = 0; y < appH; y++) {
      color c = color(110*y/appH+128, 110*y/appH+128, 110*y/appH+128);
      set(0, y, c);  
    }
  }

  for (int u = 0; u < numDragPoints; u++) {
    stroke(0, 0, 255);
    if (dragPoint == u) {
      if (dragging) {
        fill(0, 0, 255);
        strokeWeight(3);
        ellipse(dragPoints[u*2], dragPoints[u*2+1], 5, 5);
      } else {
        noFill();
        strokeWeight(3);
        ellipse(dragPoints[u*2], dragPoints[u*2+1], 6, 6);
      }
    } else {
      //noFill();
      //strokeWeight(1);
      //ellipse(dragPoints[u*2], dragPoints[u*2+1], 6, 6);
    }
  }
  noLoop();
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.