Russian Qt Forum
Май 07, 2024, 10:29 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало Форум WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  
  Просмотр сообщений
Страниц: 1 2 [3] 4 5 ... 39
31  Qt / Многопоточное программирование, процессы / Re: waitForDone : Июль 05, 2021, 09:21
Строго говоря, аналогом QThreadPool::waitForDone является QThread::wait.
Здесь же требуется дождаться выполнения всех задач в потоке.

Возможно, так получится подождать. Сам не пробовал).

Код
C++ (Qt)
thread->eventDispatcher()->processEvents( QEventLoop::AllEvents )
 
32  Qt / OpenGL / Re: Долгое рисование : Июнь 21, 2021, 21:16
Вопрос 2: а что собсно делать если отрисовка не усспевает? Полагаем что после отрисовки каждого (из 25К) объекта вызывается ф-ция IsInterrupred() (достаточно быстрая), без нее все равно не обойтись. И вот она вернула true. Дальше что?

Если в OpenGL отображать каждый элемент отдельно, то никаких ресурсов не хватит). Важным является отображение всей сцены за минимальное количество обращений к контексту OpenGL. Пока рисуется сцена, никаких обработок событий GUI производить не нужно. Формирование кадра отдельно,обработка событий GUI отдельно.

Сцена может меняться достаточно интенсивно, после каждого изменения формировать кадр расточительно. Поэтому существует метод update() для отложенного рисования.

Если сам процесс формирования кадра занимает 1.6 секунд, то требуется переделка самого процесса отображения. Для 25 тыс. объектов не большой детализации (элементы GUI) приемлемое время не более 20 мс.
33  Qt / OpenGL / Re: Долгое рисование : Июнь 21, 2021, 15:20
Полагаем что какое-то рисование есть/имеется, насколько оно быстро/оптимально - др вопрос, в любом случае найдется такой объем данных что скорость отрисовки не успеет за активностью юзера. В этой теме хотелось бы поговоритт как отрабатывать такую ситуацию

А что выносить в поток-то тогда)?
Основной профит здесь в "прореживании" и "группировке" событий. Если нет независимых этапов, то нечего и "прореживать".
Можно хоть миллион потоков сформировать, но, если поток отображения будет их ожидать, то отрисовка и взаимодействие с юзером будет тупить.
34  Qt / OpenGL / Re: Долгое рисование : Июнь 21, 2021, 13:28
Вопрос имеет архитектурный подтекст.
Как минимум, имеется несколько независимых этапа (можно выделить и больше):

- преобразование исходных данных в элементы отображаемой сцены,
- преобразование элементов сцены в данные для конвейера OpenGL,
- преобразование данных для конвейера OpenGL в кадр.

Эти этапы можно (нужно) выполнять независимо друг от друга.
При этом нет необходимости производить отображение при каждом элементарном изменении исходных данных.
На каждом этапе можно (нужно) забирать только изменения с предыдущего этапа (например, очередь изменений).
При этом события можно "проредить" (например, создание/удаление объекта и последовательное изменение одного и того же свойства и т.д.).

В OpenGL есть трудности с разделением функциональности по подготовке данных для конвейера и формированием кадра.
Если разделить все этапы, то "замерзание" GUI будет зависеть только от последнего этапа формирования кадра. А он будет зависеть от выбранной стратегии отображения - использования функциональности разных версий OpenGL, реализации шейдерных программ и т.п.
35  Программирование / Алгоритмы / Re: Найти дырки : Июнь 11, 2021, 07:36
Ну в как Вы триангулируете полигон на картинке выше?

Пользуюсь средствами GLUtessellator.
36  Программирование / Алгоритмы / Re: Найти дырки : Июнь 09, 2021, 14:56
Триангулировать "комплексные полигоны", т.е. с числом вертексов >= 5, задаются такой полилинией  

А в чем трудность в триангуляции такого полигона? Вроде, никаких артефактов для таких форм не замечал. Разве что если специальное сглаживание границ производится.

В любом случае, если решать "в лоб", то определить, находится ли один контур внутри другого, можно с помощью простой проверки - находится ли любая точка одного контура внутри геометрии другого.
Можно ещё через анализ ребер определить, но тут подумать нужно)...

А если кидаться ссылками, то можно здесь что-то полезное почерпнуть
https://doc.cgal.org/latest/Manual/packages.html#PartPolygons
https://doc.cgal.org/latest/Straight_skeleton_2/Straight_skeleton_2_2Create_skeleton_and_offset_polygons_2_8cpp-example.html
37  Программирование / Алгоритмы / Re: Найти дырки : Июнь 09, 2021, 13:49
А где (злополучная) p1 - неизвестно. Напр она может принадлежать контуру дырки...

Не получается уловить контекст вопроса). Точка может быть сразу в нескольких контурах одновременно.

Исходная то задача какая? Сформировать контуры для отображения полигонов с дырами? Или просто независимые контуры получить?
Если контуры для отображения полигонов с дырами, то там ещё немного с ребрами поработать нужно, тогда можно будет определить, когда контур будет дыркой, а когда нет.
38  Программирование / Алгоритмы / Re: Найти дырки : Июнь 09, 2021, 12:13
Реализация может быть такой.

::std::unordered_map< Point, size_t > поможет! Только нужно определить ::std::hash для типа QPointF.

1. Для каждой точки посчитать количество вхождений в последовательность (сформировать ::std::unordered_map< QPointF, size_t >).
2. Итерировать одновременно справа и слева до точек с количеством включений больше 1.
    - если точки совпали, то контур или линию получили
    - если не совпали -- есть самопересечение!
39  Программирование / Алгоритмы / Re: Найти дырки : Июнь 09, 2021, 12:00
Вроде, не сложная задача).

Если заданы точки p1,p2,p3,p4,p5,p6,p4,p7,p8,p3,p9,p1 то контуры будут следующими

p1,p2,(p3,(p4,p5,p6,p4),p7,p8,p3), p9,p1

p4,p5,p6,p4
p3,p4,p7,p8,p3
p1,p2,p3,p9,p1

То есть повторяющиеся точки - начало нового контура или линии между контурами.
Расставляем "скобки". Всё что внутри извлекаем, оставляя только одну точку.
В результате две точки - линия между контурами, больше двух - контур.
40  Программирование / С/C++ / Re: Ассоциации (?) : Апрель 28, 2021, 17:27
Если нужен свой велик для С++98, то можно что-то типа этого использовать

Код
C++ (Qt)
template < typename _Type, int >
struct EnumName { static const char * name () { return "<Unknown>"; } };
 
#define ENUM_NAME( Enum, param_value, param_name ) \
   template <>  struct EnumName< Enum, param_value > { static const char * name () { return param_name; } }; \
 
template < typename _Enum, int _value >
struct EnumNameHelper
{
   static const char * name ( int value )
   {
       if ( _value == value )
           return EnumName< _Enum, _value >::name();
       else if ( _value > value )
           return EnumNameHelper< _Enum, _value - 1 >::name( value );
       else
           return "<Incorrect>";
   }
};
 
template < typename _Enum >
struct EnumNameHelper< _Enum, -1 >
{
   static const char * name ( int ) { return "<Corrupted>"; }
};
 
template < typename _Enum >
const char * enumValueName ( _Enum value )
{
   return EnumNameHelper< _Enum, param_Count >::name( value );
}
 

Код
C++ (Qt)
enum MyEnum
{
 param_Amount,
 param_Velocity,
 param_Color,
 param_Coordinate,
 param_Count
};
 
// или так писать
template <> struct EnumName< MyEnum, param_Amount > { static const char * name () { return "Amount"; } };
// или так
ENUM_NAME( MyEnum, param_Velocity, "Velocity" )
ENUM_NAME( MyEnum, param_Color, "Color" )
ENUM_NAME( MyEnum, param_Coordinate, "Coordinate" )
 
 
#include <iostream>
 
int main ( int narg, char ** vargs )
{
   // В runtime тоже работает
   for ( size_t i = 0; i < param_Count; ++i )
       ::std::cout << enumValueName< MyEnum >( i ) << ::std::endl;
   return 0;
}
 
41  Программирование / С/C++ / Re: чтение и запись битовых структур данных : Апрель 28, 2021, 07:21
На эту тему писал свой велик. Продукт проприетарный, поэтому пока опишу только сами подходы.

Реализовывалась работа со структурами специфичного формата данных http://www.eurocontrol.int/services/asterix
Формат данных описывается в параметрическом виде, например, xml

Код
XML
   <DataItem id="020">
       <DataItemName>Target Report Descriptor</DataItemName>
       <DataItemDefinition>Type and characteristics of the radar data as transmitted by a radar station.</DataItemDefinition>
       <DataItemFormat desc="Variable length Data Item comprising a first part of oneoctet, followed by one-octet extents as necessary.">
           <Variable>
               <Fixed length="1">
                   <Bits bit="8">
                       <BitsShortName>TYP</BitsShortName>
                       <BitsValue val="0">Plot</BitsValue>
                       <BitsValue val="1">Track</BitsValue>
                   </Bits>
                   <Bits bit="7">
                       <BitsShortName>SIM</BitsShortName>
                       <BitsValue val="0">Actual plot or track</BitsValue>
                       <BitsValue val="1">Simulated plot or track</BitsValue>
                   </Bits>
                   <Bits from="6" to="5">
                       <BitsShortName>SSRPSR</BitsShortName>
                       <BitsValue val="0">No detection</BitsValue>
                       <BitsValue val="1">Sole primary detection</BitsValue>
                       <BitsValue val="2">Sole secondary detection</BitsValue>
                       <BitsValue val="3">Combined primary and secondary detection</BitsValue>
                   </Bits>
                   <Bits bit="4">
                       <BitsShortName>ANT</BitsShortName>
                       <BitsValue val="0">Target report from antenna 1</BitsValue>
                       <BitsValue val="1">Target report from antenna 2</BitsValue>
                   </Bits>
                   <Bits bit="3">
                       <BitsShortName>SPI</BitsShortName>
                       <BitsValue val="0">Default</BitsValue>
                       <BitsValue val="1">Special Position Identification</BitsValue>
                   </Bits>
                   <Bits bit="2">
                       <BitsShortName>RAB</BitsShortName>
                       <BitsValue val="0">Default</BitsValue>
                       <BitsValue val="1">Plot or track from a fixed transponder</BitsValue>
                   </Bits>
                   <Bits bit="1" fx="1">
                       <BitsShortName>FX</BitsShortName>
                       <BitsValue val="0">End of Data Item</BitsValue>
                       <BitsValue val="1">Extension into first extent</BitsValue>
                   </Bits>
               </Fixed>
               <Fixed length="1">
                   <Bits bit="8">
                       <BitsShortName>TST</BitsShortName>
                       <BitsValue val="0">Default</BitsValue>
                       <BitsValue val="1">Test target indicator</BitsValue>
                   </Bits>
                   <Bits from="7" to="6">
                       <BitsShortName>DS1DS2</BitsShortName>
                       <BitsValue val="0">Default</BitsValue>
                       <BitsValue val="1">Unlawful interference (code 7500)</BitsValue>
                       <BitsValue val="2">Radio-communication failure (code 7600)</BitsValue>
                       <BitsValue val="3">Emergency (code 7700)</BitsValue>
                   </Bits>
                   <Bits bit="5">
                       <BitsShortName>ME</BitsShortName>
                       <BitsValue val="0">Default</BitsValue>
                       <BitsValue val="1">Military emergency</BitsValue>
                   </Bits>
                   <Bits bit="4">
                       <BitsShortName>MI</BitsShortName>
                       <BitsValue val="0">Default</BitsValue>
                       <BitsValue val="1">Military identification</BitsValue>
                   </Bits>
                   <Bits from="3" to="2">
                       <BitsShortName>spare</BitsShortName>
                       <BitsName>spare bits set to 0</BitsName>
                       <BitsConst>0</BitsConst>
                   </Bits>
                   <Bits bit="1" fx="1">
                       <BitsShortName>FX</BitsShortName>
                       <BitsValue val="0">End of Data Item</BitsValue>
                       <BitsValue val="1">Extension into next extent</BitsValue>
                   </Bits>
               </Fixed>
           </Variable>
       </DataItemFormat>
   </DataItem>
 
   <DataItem id="040">
       <DataItemName>Measured Position in Polar Coordinates</DataItemName>
       <DataItemDefinition>Measured position of an aircraft in local polar coordinates.</DataItemDefinition>
       <DataItemFormat desc="Four-octet fixed length Data Item.">
           <Fixed length="4">
               <Bits from="32" to="17">
                   <BitsShortName>RHO</BitsShortName>
                   <BitsUnit max="512" scale="0.0078125">NM</BitsUnit>
               </Bits>
               <Bits from="16" to="1">
                   <BitsShortName>THETA</BitsShortName>
                   <BitsUnit scale="0.0054931640625">deg</BitsUnit>
               </Bits>
           </Fixed>
       </DataItemFormat>            
   </DataItem>
 
 

Для этого файла пишется парсер, который формирует структуры с описанием формата данных.

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

Если требуется работать с динамически изменяющимися структурами, то доступ к полям в runtime осуществляется по имени примерно так

Код
C++ (Qt)
record.item( "040" ).field( "RHO" );
 

Если состав структуры известен на этапе компиляции, то по формату xml можно сгенерировать исходники, как предлагал Old или так

Код
C++ (Qt)
 
struct Record
{
   Bytes m_bytes;
 
   // BitField< Byte number,  First bit, Last bit >
   BitField<0, 0, 1> flag;
   BitField<0, 1, 5> mode;
   BitField<0, 5, 14> address;
 
   Record () : flag( m_bytes ), mode( m_bytes ), address( m_bytes ) {}
};
 

42  Программирование / Алгоритмы / Re: Определить проекции вектора гравитации на три оси зная углы поворота по осям : Март 19, 2021, 11:20
Есть ли вариант пересчитать углы поворота вокруг осей X,Y,Z в проекции вектора гравитации на эти оси?
Тут нашел пример http://bitaks.com/resources/inclinometer/content.html,
но там приведены прямые формулы - т.е. они получают углы из проекций, а мне надо наоборот

Нужно выразить Ax, Ay, Az из представленных формул? Да...  Шокированный
Взять тангенс и возвести в квадрат каждое из уравнений и ...
Получается сложнейшая система из 3-х линейных уравнений относительно A2x, A2y, A2z.

43  Программирование / Алгоритмы / Re: Восстановление синусоиды : Март 18, 2021, 21:52
Известно, что исходный сигнал это синусоида с неким постоянным периодом.
Объем данных - массив из примерно 500-1000 сэмплов. В пределах этого массива сигнал "закольцован", т.е. его начало гарантированно совпадает с концом по  значениям амплитуды.
Вот требуется восстановить исходную синусоиду (период в общем случае не известен).
Есть ли какие-либо известные алгоритмы для этого?
"гугл не помог" пока Грустный


Есть же обычное преобразование Фурье, которое выделит и период и фазовый сдвиг синусоиды. Тем более, что начало гарантированно совпадает с концом по амплитуде (периоду). А если количество сэмплов будет кратно степени 2, то можно и fft   алгоритм  применить.
44  Qt / Многопоточное программирование, процессы / Re: Thread tried to wait on itself : Март 15, 2021, 15:12
Спасибо за напоминание, что "хэндл" живет в потоке, в котором он создан)) Но откуда следует, что остановить поток (quit) можно только из того потока, откуда он был запущен?

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

Иначе говоря, код
Код
C++ (Qt)
Worker::~Worker() {
   workerThread->quit();
   workerThread->deleteLater();
}
 
корректен?

Я считаю, что некорректен, и не стал бы его использовать, так как содержит потенциальную проблему - сегодня работает, а завтра ...
45  Qt / Многопоточное программирование, процессы / Re: Thread tried to wait on itself : Март 15, 2021, 13:11
Вот пример по шагам

Код
C++ (Qt)
// деструктор вызывается в потоке workerThread
Worker::~Worker() {
   // в потоке workerThread обращаемся к объекту главного потока workerThread
   // (возможны проблемы с конкурентным доступом) с командой завершения QEventLoop
   workerThread->quit();
 
   // в потоке workerThread обращаемся к объекту главного потока workerThread
   // (возможны проблемы с конкурентным доступом) с командой ожидания завершения активности данного потока
   // получаем игнорирование команды и не завершенный поток workerThread
   workerThread->wait();
 
   // в очередь главный поток отправляем событие удаления объекта workerThread,
   // которое может быть обработано в главном потоке даже до завершения этого деструктора,
   // когда активность потока workerThread фактически не завершена.
   workerThread->deleteLater();
}
Страниц: 1 2 [3] 4 5 ... 39

Страница сгенерирована за 0.201 секунд. Запросов: 23.