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

Войти
 
  Начало Форум WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  
  Просмотр сообщений
Страниц: 1 2 [3] 4 5 ... 39
31  Программирование / Алгоритмы / 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
32  Программирование / Алгоритмы / Re: Найти дырки : Июнь 09, 2021, 13:49
А где (злополучная) p1 - неизвестно. Напр она может принадлежать контуру дырки...

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

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

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

1. Для каждой точки посчитать количество вхождений в последовательность (сформировать ::std::unordered_map< QPointF, size_t >).
2. Итерировать одновременно справа и слева до точек с количеством включений больше 1.
    - если точки совпали, то контур или линию получили
    - если не совпали -- есть самопересечение!
34  Программирование / Алгоритмы / 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

То есть повторяющиеся точки - начало нового контура или линии между контурами.
Расставляем "скобки". Всё что внутри извлекаем, оставляя только одну точку.
В результате две точки - линия между контурами, больше двух - контур.
35  Программирование / С/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;
}
 
36  Программирование / С/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 ) {}
};
 

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

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

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


Есть же обычное преобразование Фурье, которое выделит и период и фазовый сдвиг синусоиды. Тем более, что начало гарантированно совпадает с концом по амплитуде (периоду). А если количество сэмплов будет кратно степени 2, то можно и fft   алгоритм  применить.
39  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();
}
 
корректен?

Я считаю, что некорректен, и не стал бы его использовать, так как содержит потенциальную проблему - сегодня работает, а завтра ...
40  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();
}
41  Qt / Многопоточное программирование, процессы / Re: Thread tried to wait on itself : Март 15, 2021, 12:54
Всё даже может быть намного хуже, если полностью прочитать документацию)).
Цитировать
Note that deleting a QThread object will not stop the execution of the thread it manages. Deleting a running QThread (i.e. isFinished() returns false) will result in a program crash. Wait for the finished() signal before deleting the QThread.
42  Qt / Многопоточное программирование, процессы / Re: Thread tried to wait on itself : Март 15, 2021, 12:49
Собственно, это всего лишь предупреждение, и wait в этом случае ничего не делает. Убираем wait, остается выход из циклов обработки событий quit и отложенное удаление объекта QThread с помощью deleteLater. Вопрос остается - это правильно?

Удаление объекта QThread само по себе не завершает активность (Note that deleting a QThread object will not stop the execution of the thread it manages.).
Метод wait же ожидает завершения активности.

В общем случае, второй вариант допускает "подвешивание" незавершенных активностей, особенно если они реализованы в виде бесконечных циклов (когда реализована собственная версия метода MyThread::run() ).
43  Qt / Многопоточное программирование, процессы / Re: Thread tried to wait on itself : Март 15, 2021, 11:42
ждать в себе завершения самого себя бессмысленно)).

Это ж и есть ответ на вопрос.

Вызов деструктора Worker производится в активности потока workerThread, который и предлагается подождать с помощью workerThread->wait().
В первом же варианте вызов деструктора Controller производится в активности другого (скорее всего, главного) потока, связанного с объектом Controller. Здесь можно и подождать workerThread->wait().
44  Qt / Многопоточное программирование, процессы / Re: Не масштабится :-( : Март 12, 2021, 12:43
Написал пример С++17. Ускорение есть какое-то в пару раз, но для поставленных амбициозных целей явно не подходит).
Возможно и ошибся где-то. А так-то, сразу тестовая программка сильно помогла бы вникнуть в вопрос.
45  Qt / Многопоточное программирование, процессы / Re: Не масштабится :-( : Март 10, 2021, 16:48
Такое "деление на диапазоны" (иногда называют "stencil") совсем не бесплатно/безобидно. И предрассчитать его получается далеко не всегда.

Найти (или предположить) диапазон значений индексов - откуда здесь могут быть большие затраты?

Я бы делал просто "мешком локеров", напр для Qt

Любые локеры сделают только хуже. Здесь может только помочь распараллеливание безо всяких локеров. Все потоки пробегаются по всему циклу, только производят вычисления каждый в своем диапазоне. В своих задачах я формирую массивы типа faces заранее (увеличиваю только при необходимости), чтобы не иметь потерь на new|delete.
Использование заранее инициированного пула потоков и ожидание на барьере после первого цикла и далее после второго ничтожно по сравнению с затратами на вычисления.
И да, расчеты нормалей, как правило делают на GPU.
Страниц: 1 2 [3] 4 5 ... 39

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