[CDR X5-X8] при пакетной обработке не всегда видится шейп (Непредсказуемый IsOnShape)

  • Автор темы Автор темы Nezar
  • Дата начала Дата начала
Статус
Закрыто для дальнейших ответов.

Nezar

Участник
Топикстартер
Сообщения
158
Реакции
3
дурацкое название темы. постараюсь объяснить проблему.

есть некий макрос, который пробегает по всем шейпам и с каждым выполняет ряд операций.
такие как
Set a = ActiveShape.DisplayCurve.FindClosestSegment(x, y, po).GetPointAt(po)
ddd = sm.IsOnShape(xc, yc)
но проблема в том что если я скопирую с какого то документа шейпы, вставлю на новую страницу и запущу макрос то функция ddd = sm.IsOnShape(xc, yc) в 90 процентов случаев вернет 0 - что в заданных координатах нет шейпа.
но после второго запуска, без каких либо изменений эта ошибка возникает всего в 10 процентах случаев.
я не могу понять и вычислить почему она возникает, т.к. она плавающая и предсказать ее невозможно.
может кто то сталкивался с проблемой невидимости шейпов при первом запуске и видимости при последующем?
может как то правильно и особо их надо объявить?
может есть какие то хитрости?
я уже вторую ночь бьюсь но не получается решить проблему.
Спасибо.
 
Таки да, я с самого начала предупреждал, что IsOnShape - чертовски глюкавая функция и сильно заморачиваться на нее не стоит :(
 
помню, но надеялся что повезет )).
не думал что на столько сильно будет глючить.
т.е. не мучатся и обойти ее.
 
нашел закономерность.
если запускать макрос и при этом уменьшить масштаб примерно до 10-1% то не все шейпы отрабатываютсмя нормально.
если же увеличить примерно до 100000% - то все работает нормально.
проверил раз 10 - и это реальная закономерность.
от сюда возник вопрос, а как связан текущий масштаб страницы с работой макроса?

в начале макроса устанавливаю единицы так
ActiveDocument.Unit = cdrMillimeter
может это как то влияет?
 
вроде разобрался
я уже описывал проблему при работе IsOnShape, в частности определения вхождения точки в границу контура.
эта самая граница контура неизменна, и даже если она задана как нулевая - она все равно имеет размер.
а самый маразм в том что этот размер всегда один и не меняется в зависимости от текущего масштаба документа.
т.е. если масштаб очень мелкий то эта самая граница легко перекрывает собой контур, к которому относится. и поэтому IsOnShape будет возвращать попадание в границу, даже если это не так.
бред полный.
лечится просто - увеличением масштаба до максимума, тогда граница "уменьшается" до минимума относительно текущего масштабного размера контура и в нее практически невозможно попасть....
IsOnShape есть третий параметр, который вроде как задает чувствительность, пробовал всевозможные цифры - но чувствительность только падала, т.е. возрастала толщина виртуальной границы.
 
лечится просто - увеличением масштаба до максимума, тогда граница "уменьшается" до минимума относительно текущего масштабного размера контура и в нее практически невозможно попасть....
Меня терзают смутные сомнения, что IsOnShape реализован нечестно - вместо того, чтобы геометрически проверять входит точка в шейп или нет, они для простоты и ускорения где-то внутри растрируют шейп и проверяют на попадание в закрашенную область. Соответственно, реальный размер растрированного шейпа привязан к экранному, т.е. к текущему масштабу. Но это чисто мое имхо, в код я не лазил.
 
По давним опытам помнится, что IsOnShape зависит от режима просмотра, т.е. может выдавать неверный результат при запуске в режиме WireframeView и правильно работать в Normal/Enhanced.
 
По давним опытам помнится, что IsOnShape зависит от режима просмотра
Ну это какбэ, косвенно подтверждает мое предположение
Скажем, шейп перед выводом на экран где то в буфере у корела отрисовывается и оттуда же считается результат для данной функции.
А иначе там нехилая математика, причем, весьма небыстрая
 
Математика там не такая уж и сложная.
 
Делал я её, ничего сложного не увидел.
 
Может погуглишь?
Кидается луч из точки, для простоты по ординате или абсциссе, перебираются и подсчитываются пересекаемые участки, отдельная обработка на совпадение луча со стороной или с углом, ну и Безье для простоты на набор отрезков бьёшь. Winding ещё выбираешь. Нету там развёрток.
 
И чего? For Each seg in Shape.Curve.Segments поломался?
 
Аппроксимировал Безье отрезками. При желании интересный кусок ещё сильнее бил. Корней не считал.
 
Аппроксимировал Безье отрезками. При желании интересный кусок ещё сильнее бил. Корней не считал.
Ну это совсем грубое приближение, чем оно интересно лучше IsOnShape?
Вот такую ты тоже отрезками аппроксимировать будешь?
upload_2017-2-27_16-32-7.png
 
Опыты ставил в доIsOnShape'ные времена.
Буду. Почему нет?
 
Вот тоже столкнулся с этой проблемой - автору как-то удалось достичь +/- стабильной работы функции? Или найти альтернативу?
 
Статус
Закрыто для дальнейших ответов.