Объект "Plan Marker"
Доброго Времени Суток!
Сегодня разбор очередного GDL-объекта с изощренной 2D начинкой, в виде кучки АС(Активные споты - для редактирования объекта в окне(2D,3D)) и организации их поведения. На примере данного объекта будет показано как организовать интерактивное редактирование объекта на плане. Т.е. сделать так, чтобы каждый раз не лезть в диалог установки параметров, что IMHO лишний раз делать не хочется, даже если там супер-пупер разукрашенная вкладка интерфейса.
=======================================================================
=======================================================================
INTRO:
объект представляет собой "компоновку" из трех различных по назначению маркеров:
1. Первый маркер - это позиция детали на КМД (не обязательно) чертеже, выглядит маркер как кружок с линией-выноской, внутри которого текст - номер позиции детали.
Логическая нагрузка:
1.1 интерактивный выбор номера позиции(АС-1, углового типа);
1.2 число линий выносок от 0 до 10, задается в меню объекта;
1.3 редактирование положения выноски, выноска начинается в АС-2 и заканчивается на контуре круга маркера;
1.4 правильная отрисовка при изменении масштаба окна. Сомнительная необходимость, тем не менее реализовано.
1.5 в меню задаются остальные моменты оформления маркера - размер, перья, штриховка.
1.6 данные для обработки интерактивным каталогом(количество, ед.изм., наименование); реализовано в следующих целях - в соответствии с ГОСТ 21.501 рабочая документация по большому счету состоит из схем расположения и спецификаций к ним. При этом на схемах расположения учитываемые конструкции изображаются условно, в соответствии с принятыми условными обозначениями. Например балка изображается линией, план перекрестных балок - набор линий, не замкнутых друг на друга , т.е. я хочу сказать что используя технологию BIM, необходимо будет потратить время на приведение автоматически сгенерированных планов/разрезов к ГОСТ. IMHO, в данном случае модель избыточна, достаточно нарисовать подобную схему 2Д примитивами, и используя параметры (количество, ед.изм., наименование) предусмотренные в данном маркере обсчитать схему при помощи ИК.
Скрин 1. Маркер "Позиция".
2. Маркер для указания типа полов в помещении. В виде равностороннего треугольника с номером типа пола. Т.е. в рабочем проекте существует экспликация полов, в которой эта нумерация типов полов и отражается. Речь идет о таблице ГОСТ 21.501.
Тут стоит сказать пару слов. Вообще этот маркер не является ГОСТовским изображением, ГОСТ не дает указаний относительно вида маркера полов. Как правило, план полов отдельно не выполняется, и типы полов соответственно приводятся в экспликации полов, т.е. в строке по каждому типу приводится список номеров помещений в которых предусматривается данный вид полов. (В общем все в курсе, я просто решил помять клавиши...) Тем не менее этот маркер достаточно "закрепился" в оформлении рабочих чертежей АС. И потому добавлен в компоновку объекта. Также моей вольностью было добавить возможность этому маркеру иметь линии-выноски, с целью маркировать полы в мелких при данном масштабе помещениях.
Логическая нагрузка:
По аналогии с маркером "номер позиции"+селектор - привязка линий выносок, 2 варианта:
-к ближайшей вершине маркера;
-к указанной вершине маркера, т.е возможна привязка к 3 точкам, указывается спотом(скрин 2.2) ;
Параметр "размер маркера" в случае "треугольника" задает диаметр описанной, на котором и нужно искать АС-1.
Скрин 2.1. Маркер "Тип пола".
Привязка линий-выносок к ближайшей вершине.
Скрин 2.2. Маркер "Тип пола".
Привязка линий-выносок к указанной вершине.
3. Маркер измененного участка чертежа. Этот маркер регламентируется ГОСТ 21.1101. В нормативе приведены все сведения - как где и когда применять этот маркер.
Логическая нагрузка:
По аналогии с маркером "номер позиции"+регламентированная ГОСТ 21.1101 функциональность;
- так как заранее нельзя знать какой размер шрифта будет использован, то вся свистопляска относительно размеров параллелограма, положению АС-4, основана на выбираемом размере шрифта;
- привязка линий выносок, возможна к 4-м точкам - узлам параллелограма, указывается спотом АС-4;
- при горизонтальном отзеркаливании параллелограм должен сохранять свою "ориентацию", т.е. сам контур маркера не должен разворачиваться при операции отзеркаливания(см.видео);
- параметры для ИК(интерактивный каталог) здесь не нужны;
Скрин 3.1. Маркер "Измененный участок".
Редактирование текста.
Скрин 3.2. Маркер "Измененный участок".
Редактирование привязки выносок.
Скрин 3.3. Маркер "Измененный участок".
Редактирование положения маркера.
Назад, к баранам:
Решающим моментом, по включению в один объект этих трех маркеров послужило то, что все они являются элементами оформления чертежа. Как правило, все они существуют в одном проекте и будет правильно и удобно не ползать в библиотеку чтобы найти и выбрать один из них. А в конкретном проекте, на конкретном листе копировать один из размещенных, например маркеров "позиция детали" и, изменив ему тип, на "участок изменений" настроить его нужным образом, т.е. обойтись без поиска по библиотеке, что согласитесь УДОБНО.
Но есть и другая сторона - почему бы не включить в сборку кучу других маркеров? Например маркеры разрезов, узлов? Первое - эти маркеры есть в составе инструментов Арчика. Разумеется свой объект всегда будет удобнее чем предлагаемый, потому лишь что свои вещи как правило и являются результатом "ленивого труда", т.е. день за днем что-то все время неустраивает, нервирует, и рано или поздно настает момент действий - написание своего. А второе - это момент, который с условной натяжкой - все таки GDL, довольно специфический синтаксис, чтобы применять к нему общепринятые абстракции - закон возрастающей сложности кода, здесь это неплохо изложено:
"Вам кажется, что имея в два раза больше кода, ваша программа будет только вдвое сложнее. На самом деле, каждый раз, когда вы увеличиваете объем кода, сложность программы возрастает экспоненциально. Каждое маленькое дополнение, каждое изменение, каждая взаимозависимость и каждое предпочтение имеют каскадный эффект. Продолжайте безбоязненно добавлять код, и вы получите страшный Большой Ком Грязи — до того, как это заметите.
Как бороться с этой сложностью — уменьшением объема программы. Уменьшение объема программы значит меньше функций, меньше кода, меньше отходов."
http://www.libma.ru/delovaja_literatura/getting_real/p11.php
Вывод делаю следующий: надо хорошо представлять весы "реальная польза - реальная сложность", если перевешивает сложность, стоит подумать о макросах, разбиении проекта, других (кроме GDL скрипта) способах решения задачи. Например, вполне существенны и эффективны (в области "инженерных" объектов) решения, когда GDL является лишь "построителем" а "интерфейс и основная логика" объекта - это один из вариантов:
- примочка арчика - AddOn(C++, *.apx),
- Excel и макросы сохраняющие результаты работы в *.txt, *.csv - файлы которые можно скормить построителю. Не помню где прочитал, но полностью подпишусь: "Excel -это бейсик, лучший чем сам Бейсик", а от себя добавлю что Excel в умелых руках - это все что может потребоваться инженеру.
- Любой внешний проект(еще более общий случай), с интерфейсной частью и логикой, результатом работы которого является "выхлоп", в одном из форматов, которые может читать GDL-скрипт - txt, csv, bin, xml. Этот вариант интересен, в первую очередь тем, что полностью развязывает руки разработчику - нет необходимости регистрироваться в качестве разработчика, нет необходимости ковырять на мой взгляд не самый аппетитный Graphisoft API. Полная свобода инструментов. Обратная сторона - нет некоторых возможностей обусловленный именно родным API, но таких необходимости таких случаев скорее меньше, если не сказать что это вообще специфика. Меньше вероятность ошибок. Хотя есть и существенные моменты, об этом в "О целесообразности написания своего объекта, и его проектировании". См. в конце статьи.
=======================================================================
=======================================================================
1. ПАРАМЕТРЫ
Итак, чтобы исполнять вышеобозначенную логику объект имеет следующие параметры.
Скрин 4. Параметры.
Обращаем внимание на то, что первые 20 параметров скрытые, то есть конечный пользователь не увидит их в меню, это и есть рабочие лошадки интерактива - привязки, углы, текстовки.
Относительно конкретных параметров:
FSC - нужен для пересчета размеров маркера при изменении масштаба окна(плана/разреза/фасада); такое бывает не часто, тем не менее реализовано. Обычная практика - в макете указать масштаб вьюпорта, там проблем ни с одним объектом быть не может, работает Арч. (IMHO).
AX,BX - поправки отвечающие за "пузатость" контура параллелограма(чтобы текст не залезал на контур маркера)
XC - массив АС - координат окончаний линий-выносок. Поэтому, переключая типы выносок если вновь выбранный маркер может иметь выноски - они останутся на своих местах, разумеется, если были ранее расставлены. Не может иметь выносок маркер 3, параллелограм в случае если объект символизирует участок-дополнение, тут автоматом скрипт параметров выставит значение NN в ноль.
Скрин 5. Маркер "Измененный участок.Дополнение".
sAng - с юзернэймом "первый разряд", это параметр завязанный на АС-угол, в маркере "Позиция детали", по его значению вычисляется текст размещаемый в маркере.
rAng1,rAng2 - аналогично, текст номера и участка изменения в маркере 3
dAng - текст маркера "тип пола";
rad1,rad2 - параметры размера маркера, задаются пользователем в меню, в конечных единицах, в мм(или какие установлены у вас в Арче в качестве единиц длины);
rad1s,rad2s -тоже, внутренние, пересчитанные в масштабе окна; пользователю недоуступны;
параметры из раздела "установки"(3шт) - задают пределы изменения числовых значений
отображаемых в маркерах (соответственно названию). - параметры с индексом SM... - смета, для ИК.
=======================================================================
=======================================================================
2. СКРИПТ ПАРАМЕТРОВ
Итак, смотрим как реализована требуемая логика:
!X1,Y1 - центр маркера, для всех типов маркера в этой точке отрисовывается текст.
! - получаем массив установленных шрифтов;
dim fontNames[]
n = request("FONTNAMES_LIST", "", fontNames)
values "F" fontNames,
custom
! - размер шрифта не менее 1мм;
values "FS" range[1,)
! - число линий-выносок;
values "NN"
0,1,2,3,4,5,6,7,8,9,10
! FSC Искать в основном скрипте
! - описана логика вычисления точек привязки линий-выносок к углам контура в маркере "параллелограм";
values "X2" X1-AX*FSC,X1+AX*FSC,X1-BX*FSC,X1+BX*FSC
IF (X2=X1-AX*FSC) or (X2=X1+BX*FSC) then
values "Y2" Y1+FSC
endif
IF (X2=X1+AX*FSC) or (X2=X1-BX*FSC) then
values "Y2" Y1-FSC
endif
! - значения иксов для привязок линий-выносок треугольника, X1,Y1 - центр маркера;
! - и соответствуюшие иксам игреки.
values "X3" x1, x1-rad1*cos(30),x1+rad1*cos(30)
IF (X3=x1-rad1*cos(30)) or (X3=x1+rad1*cos(30)) then
values "Y3" y1-rad1*cos(60)
endif
IF (X3=x1) then
values "Y3" y1+rad1
endif
! - без коментов
values "type" "Круг", "Треугольник",
"Параллелограм"
values "remark_type" "Просто
измененный участок","См.лист","Взамен перечеркнутого на
листе","Дополнение","Аннулировано"
values "snap_type" "К ближайшей вершине", "К
указанной вершине"
!=============================================
! - используем программный стек для хранения значений углового параметра
if type="Круг"
then
xx=pos_max
For x=1 to xx
PUT INT(360/xx)*x
NEXT x
! - назначаем параметру sAng все вычисленные и сохраненные в стеке параметры; команда GET очищает стек.
values "sAng" GET(NSP)
! - назначаем параметру sAng все вычисленные и сохраненные в стеке параметры; команда GET очищает стек.
values "sAng" GET(NSP)
endif
if type="Параллелограм" then
xx=izm_max
For x=1 to xx
PUT INT(360/xx)*x
NEXT x
! - назначаем параметрам rAng1,2 все вычисленные и сохраненные в стеке параметры; команда USE НЕ-очищает стек. Поэтому параметр rAng2 получит данные аналогичные rAng1
values "rAng1" USE(NSP)
values "rAng2" USE(NSP)
endif
! - аналогично, в соответствии с установкой pol_max заполняем список возможных значений для dAng, передаем его параметру из стека,очищаем стек.
if type="Треугольник" then
xx=pol_max
For x=1 to xx
PUT INT(360/xx)*x
NEXT x
values
"dAng" GET(NSP)
endif
=======================================================================
=======================================================================
3. ОСНОВНОЙ СКРИПТ
! - необходимость пользовательского текста(т.е. в маркере можно нарисовать и букву и использовать его как маркер оси %)
if IsCustomText=0 Then
HIDEPARAMETER "CustomText"
Endif
! - необходимость штриховки, обратите внимание как повешены друг на друга параметры перья и тип штриховки(на вкладке параметры и в основном скрипте), таким образом пользователь получает для ввода только те параметры которые подразумеваются его выбором, т.е. выбрал "штриховать" - появился тип штриховки и аттрибуты штриховки, это полезно с точки зрения распределения внимания. Бывает откроешь менюху объекта а там 200 параметров!!! куда смотреть, за что цепляться? IMHO - если уж заставляешь пользователя лезть в меню - "приберись" там.
if IsFill=0 Then
HIDEPARAMETER "Fill_type"
Endif
! прячем ненужные для круга параметры
if type="Круг"
then
HIDEPARAMETER "remark_type" ,"listref",
"snap_type", "sm_area", "sm_floor_type"
if IsCustomText=0
Then
! - забираем для сметы
! - забираем для сметы
PARAMETERS
Sm_poz=atext
else
PARAMETERS
Sm_poz=CustomText
endif
endif
Endif
! прячем ненужные для параллелограма параметры
if type="Параллелограм" then
HIDEPARAMETER "rad1s", "rad2s",
"snap_type", "spsp"
if remark_type="Дополнение" or remark_type="Аннулировано" or remark_type="Просто измененный
участок" Then
HIDEPARAMETER "ListRef"
! для участка типа "дополнение" число выносок ставим в ноль.
if remark_type="Дополнение" Then
PARAMETERS XC=0, nn=0
Endif
Endif
Endif
! прячем ненужные для треугольника параметры
if type="Треугольник" then
HIDEPARAMETER "remark_type" ,"listref",
"sm_poz", "sm_oboz", "sm_naim",
"sm_edizm", "sm_kolvo"
! - забираем для сметы
if IsCustomText=0 Then
PARAMETERS
Sm_floor_type=dtext
else
PARAMETERS
Sm_floor_type=CustomText
endif
endif
Endif
! - задаем точность вычисления положения угловых АС
EPS = 0.0001
! - кратность угловых параметров в соответствии с разделом параметров "установки"
alfa = INT(360/pos_max)
beta = INT(360/izm_max)
gama = INT(360/pol_max)
! step x6 angle
!!! ---------- Text Selection Angle 1 ----------
! - если последним измененным параметром был sAng, то смотрим сколько градусов было выставлено, устанавливаем текущее положение углового АС, передаем текстовому параметру atext "меру кратности", т.е номер позиции в маркере.
if GLOB_MODPAR_NAME = "sAng" then
if GLOB_MODPAR_NAME = "sAng" then
for x=1 to pos_max
if
abs (sAng-alfa* x) < EPS then
PARAMETERS
atext=str(x,1,0)
endif
next x
endif
! таже петрушка для параллелограмма
! таже петрушка для параллелограмма
!!! ---------- Text Selection Angle 2 ----------
if GLOB_MODPAR_NAME
= "rAng1" then
for x=1 to izm_max
if abs (rAng1-beta* x) < EPS then
parameters
btext=str(x,1,0)
endif
next x
endif
!!! ---------- Text Selection Angle 3 ----------
if GLOB_MODPAR_NAME
= "rAng2" then
for x=1 to izm_max
if
abs (rAng2-beta* x) < EPS then
parameters
ctext=str(x,1,0)
endif
next x
endif
! таже петрушка для треугольника
!!! ---------- Text Selection Angle 4 ----------
if GLOB_MODPAR_NAME
= "dAng" then
for x=1 to pol_max
if
abs (dAng-gama* x) < EPS then
parameters
dtext=str(x,1,0)
endif
next x
endif
!!! ---------- SCALING ----------
! Масштабирование, отрисовка всех трех маркеров связана с заданными размерами, т.е. с параметрами rad1, rad2; GLOB_SCALE - глобальная переменная-константа, т.е. определена до начала интерпретации GDL-скрипта
sc=GLOB_SCALE
sc=GLOB_SCALE
PARAMETERS RAD1=RAD1s*sc,
RAD2=RAD2s*sc, FSC=FS/(1000)*sc
=======================================================================
=======================================================================
4. 2D СКРИПТ
!/SABRUS
2012
! два текстовых стиля, "по центру"-для текста в маркере, с привязкой "слева" - для текстовок в параллелограме.
DEFINE
STYLE "TST" F, FS,5,0
DEFINE
STYLE "DST" F, FS,7,0
SET STYLE
"TST"
! номера меток, на которые будем переходить после рисования общей части.
Krug=10
Parall=20
Triangle=30
Finish=40
!===================
штриховка,если нужна
IF isfill
then
SET FILL
Fill_type
endif
!=======точка центр, она же печъъка.
! АС-3(согласно скринам вначале), центр маркера X1,Y1.
HOTSPOT2
X1,0,3,Y1,1+128
HOTSPOT2
X1,-1,4,Y1,3
HOTSPOT2
X1,Y1,5,Y1,2
HOTSPOT2
0,Y1,6,X1,1+128
HOTSPOT2
-1,Y1,7,X1,3
HOTSPOT2
X1,Y1,8,X1,2
!=========дальше по типу выноски ============
UnID=15
!==Указательный камень ==============
if type="Круг" then goto Krug
if
type="Параллелограм"
then goto Parall
if
type="Треугольник"
then goto Triangle
!=============================================
10:
! Маркер "позиция детали"
! Маркер "позиция детали"
!========текстовка ==============
pen pen3
if
not(IsCustomText) then
text2
x1,y1, atext
else
text2
x1,y1, CustomText
Endif
!======== линии-выноски ==========
for x=1 to
nn
! АС-2
HOTSPOT2
xc[x][1], 0, UnID+1,
xc[x][2],1+128
HOTSPOT2
xc[x][1], -1, UnID+2, xc[x][2],3
HOTSPOT2
xc[x][1], xc[x][2],UnID+3,
xc[x][2],2
HOTSPOT2 0, xc[x][2], UnID+4, xc[x][1],1+128
HOTSPOT2
-1, xc[x][2], UnID+5, xc[x][1],3
HOTSPOT2
xc[x][1], xc[x][2], UnID+6, xc[x][1],2
!================================================================
! Смотрим в каких четвертях обретается конец данной линии-выноски
alpha=ATN((xc[x][2]-Y1)/(xc[x][1]-X1+0.0001))
dx=Rad1*COS(alpha)
dy=Rad1*SIN(alpha)
ch1=(XC[x][1]>X1)&
(XC[x][2]>Y1)
ch2=(XC[x][1]<=X1)&(XC[x][2]>Y1)
ch3=(XC[x][1]<X1)&
(XC[x][2]<=Y1)
ch4=(XC[x][1]>=X1)&(XC[x][2]<Y1)
if ch1 then
chx=1:chy=1
endif
if ch2 then
chx=-1:chy=-1
endif
if ch3 then
chx=-1:chy=-1
endif
if ch4 then
chx=1:chy=1
endif
pen pen4
! вот он отрезок заканчивающийся на контуре маркера
! вот он отрезок заканчивающийся на контуре маркера
line2
x1+chx*dx,y1+chy*dy,xc[x][1],xc[x][2]
!================================================================
UnID=UnId+6
pen pen2
circle2
XC[x][1],XC[x][2], rad2
next x
!================================================================
!v1: Text
Edit hotspot
! АС-1 угловой спот повешенный на параметр sAng
add2 x1,y1
!!!
---------- Selector ----------
uid = UnID+1
hotspot2 0, 0, uid : uid =
uid+1 ! centre
xx = rad1*cos(sAng)
yy = rad1*sin(sAng)
hotspot2 0, 0,
uid, sAng, 6 : uid = uid+1 ! centre
hotspot2 rad1, 0, uid, sAng, 4+128 : uid = uid+1 ! base
hotspot2 xx , yy,
uid, sAng, 5, atext : uid = uid+1 ! moving
del 1
!=======================================
pen pen1
circle2
x1,y1,rad1
!======штрихуем
If IsFill
then
! статус коды команды есть в руководстве по GDL, без них ничего не заштриховать.
! статус коды команды есть в руководстве по GDL, без них ничего не заштриховать.
POLY2_B
2,2, pen5, pen6,
x1,y1, 900,
Rad1, 360, 4000
endif
!йохоу, один есть.
Goto Finish
!============Выноска- параллелограм
20:
! эти строчки делают параллелограм "незеркальным"
IF SYMB_MIRRORED then
mul2 -1, 1
ENDIF
!========текстовка ==============
pen pen3
if
not(IsCustomText) then
text2
x1,y1, btext+"."+ctext
else
text2 x1,y1, CustomText
Endif
!=======точка привязка линий-выносок, по углам
параллелограма.
HOTSPOT2
X2,0, UnID+1,Y2,1+128 :
UnID=UnID+1
HOTSPOT2
X2,-1,UnID+1,Y2,3 :
UnID=UnID+1
HOTSPOT2
X2,Y2,UnID+1,Y2,2 :
UnID=UnID+1
HOTSPOT2
0,Y2, UnID+1,X2,1+128 :
UnID=UnID+1
HOTSPOT2 -1,Y2,UnID+1,X2,3 : UnID=UnID+1
HOTSPOT2
X2,Y2,UnID+1,X2,2 :
UnID=UnID+1
!==============
разлиновка параллелограма
pen pen1
FSC=FS/(1000)*A_
LINE2
X1-BX*FSC,Y1-FSC,X1-AX*FSC,Y1+FSC
LINE2
X1-AX*FSC,Y1+FSC,X1+BX*FSC,Y1+FSC
LINE2
X1+BX*FSC,Y1+FSC,X1+AX*FSC,Y1-FSC
LINE2
X1+AX*FSC,Y1-FSC,X1-BX*FSC,Y1-FSC
!======штрихуем
If IsFill
then
POLY2_B
4,6, pen5, pen6,
X1-BX*FSC,Y1-FSC,600,
X1-AX*FSC,Y1+FSC,0,
X1+BX*FSC,Y1+FSC,0,
X1+AX*FSC,Y1-FSC,0
endif
! рисование текстов по ГОСТ
SET STYLE
"DST"
if
remark_type="См.лист" or remark_type="Взамен перечеркнутого на листе" then
pen pen3
text2
X1+BX*FSC,Y1-FSC,remark_type+" "+ListRef
pen pen4
line2
X1+AX*FSC,Y1-FSC,X1+(STW((remark_type)+"WWW"+ListRef)/1000*GLOB_SCALE),
Y1-FSC
endif
if
remark_type="Дополнение" or remark_type="Аннулировано" then
pen pen3
text2
X1+BX*FSC,Y1-FSC,remark_type+" "
pen pen4
line2
X1+AX*FSC,Y1-FSC,X1+(STW((remark_type)+"WWW")/1000*GLOB_SCALE),
Y1-FSC
endif
!======== линии-выноски ==========
for x=1 to
nn
HOTSPOT2
xc[x][1], 0, UnID+1,
xc[x][2],1+128
HOTSPOT2
xc[x][1], -1, UnID+2, xc[x][2],3
HOTSPOT2
xc[x][1], xc[x][2],UnID+3,
xc[x][2],2
HOTSPOT2 0, xc[x][2], UnID+4, xc[x][1],1+128
HOTSPOT2
-1, xc[x][2], UnID+5, xc[x][1],3
HOTSPOT2
xc[x][1], xc[x][2], UnID+6, xc[x][1],2
pen pen4
line2
x2,y2,xc[x][1],xc[x][2]
!================================================================
UnID=UnId+6
next x
!================================================================
add2 x1,y1
! эти два угловых АС, ответственных за композитную строку:
Номер изменения+"."+участок
Номер изменения+"."+участок
!!!
---------- Selector "Изменение" ----------
uid = UnID+1
hotspot2 0, 0, uid : uid =
uid+1 ! centre
xx = rad1*cos(rAng1)
yy = rad1*sin(rAng1)
hotspot2 0, 0,
uid, rAng1, 6 : uid = uid+1 ! centre
hotspot2 rad1, 0, uid, rAng1, 4+128 : uid = uid+1 ! base
hotspot2 xx , yy,
uid, rAng1, 5, btext : uid = uid+1 ! moving
!!!
---------- Selector "Участок" ----------
uid = UnID+1
hotspot2 0, 0, uid : uid =
uid+1 ! centre
xxx = 1.2*rad1*cos(rAng2)
yyy = 1.2*rad1*sin(rAng2)
hotspot2 0, 0,
uid, rAng2, 6 : uid = uid+1 ! centre
hotspot2 1.2*rad1, 0, uid, rAng2, 4+128 : uid = uid+1 ! base
hotspot2 xxx , yyy,
uid, rAng2, 5, ctext : uid = uid+1 ! moving
! удаляем не зеркальность
IF
SYMB_MIRRORED then
del 1
ENDIF
! удаляем смещение add2 x1,y1
del 1
! второй маркер готов
Goto Finish
!============Выноска-треугольник
30:
! почему то закончить хотелось на треугольнике )
!========текстовка ==============
pen pen3
if
not(IsCustomText) then
text2
x1,y1, dtext
else
text2
x1,y1, CustomText
Endif
!=======точка привязка линий-выносок, по углам треугольника.
If snap_type="К указанной вершине" then
HOTSPOT2
X3,0, UnID+1,Y3,1+128 :
UnID=UnID+1
HOTSPOT2
X3,-1,UnID+1,Y3,3 :
UnID=UnID+1
HOTSPOT2
X3,Y3,UnID+1,Y3,2 :
UnID=UnID+1
HOTSPOT2
0,Y3, UnID+1,X3,1+128 :
UnID=UnID+1
HOTSPOT2
-1,Y3,UnID+1,X3,3 :
UnID=UnID+1
HOTSPOT2
X3,Y3,UnID+1,X3,2 :
UnID=UnID+1
endif
!======== линии-выноски ==========
for x=1 to
nn
HOTSPOT2
xc[x][1], 0, UnID+1,
xc[x][2],1+128
HOTSPOT2
xc[x][1], -1, UnID+2, xc[x][2],3
HOTSPOT2
xc[x][1], xc[x][2],UnID+3,
xc[x][2],2
HOTSPOT2 0, xc[x][2], UnID+4, xc[x][1],1+128
HOTSPOT2
-1, xc[x][2], UnID+5, xc[x][1],3
HOTSPOT2
xc[x][1], xc[x][2], UnID+6, xc[x][1],2
!================================================================
! Оцениваем расстояния от конца линии выноски до вершин, извлекать корень не обязательно, найти ближайшую вершину можно и по оценке суммы квадратов.
rst1=(xc[x][1]-(x1-rad1*cos(30)))^2+(xc[x][2]-(y1-rad1*cos(60)))^2
rst1=(xc[x][1]-(x1-rad1*cos(30)))^2+(xc[x][2]-(y1-rad1*cos(60)))^2
rst2=(xc[x][1]-(x1+rad1*cos(30)))^2+(xc[x][2]-(y1-rad1*cos(60)))^2
rst3=(xc[x][1]-x1)^2+(xc[x][2]-(y1+rad1))^2
rst=min(rst1,
rst2,rst3)
if RST=RST1
then
fx=x1-rad1*cos(30)
fy=y1-rad1*cos(60)
endif
if RST=RST2
then
fx=x1+rad1*cos(30)
fy=y1-rad1*cos(60)
endif
if RST=RST3
then
fx=x1
fy=y1+rad1
endif
pen pen4
If
not(snap_type="К указанной вершине") then
line2
fx,fy,xc[x][1],xc[x][2]
else
line2
x3,y3,xc[x][1],xc[x][2]
endif
pen pen2
circle2
XC[x][1],XC[x][2], rad2
!================================================================
UnID=UnId+6
next x
!================================================================
!v1: Text
Edit hotspot
add2 x1,y1
!!!
---------- Selector ----------
uid = UnID+1
hotspot2 0, 0, uid : uid =
uid+1 ! centre
xx = rad1*cos(dAng)
yy = rad1*sin(dAng)
hotspot2 0, 0,
uid, dAng, 6 : uid = uid+1 ! centre
hotspot2 rad1, 0, uid, dAng, 4+128 : uid = uid+1 ! base
hotspot2 xx , yy,
uid, dAng, 5, dtext : uid = uid+1 ! moving
pen pen1
! рисуем сам треугольник
! рисуем сам треугольник
line2 0,
rad1,-rad1*cos(30),-rad1*cos(60)
line2 -rad1*cos(30),-rad1*cos(60),rad1*cos(30),-rad1*cos(60)
line2 rad1*cos(30),-rad1*cos(60),0,rad1
!======штрихуем
If IsFill then
POLY2_B 3,6, pen5, pen6,
0,
rad1, 600,
-rad1*cos(30),-rad1*cos(60),
0,
rad1*cos(30),-rad1*cos(60),0
endif
!=======================================
del 1
Goto Finish
!===тпрруууу
40:
! Del 1
End
=======================================================================
=======================================================================
ИТАК, в данном объекте показаны следующие моменты:
1. Редактирование текстовой, в данном случае числовой "информации" через АС(активные споты), в данном случае углового типа. Попробую расширить этот результат. Сделать некие выводы:
Extended 1: Ничто не мешает сделать перебор через АС заданных в массиве строк, для этого нужно в текстовый параметр передавать не переменную цикла, а значение ячейки массива по переменной цикла:
if GLOB_MODPAR_NAME = "sAng" then
for x=1 to pos_max
if
abs (sAng-alfa* x) < EPS then
PARAMETERS
atext=MyStringEnumerationArray[x]
endif
next x
endif
здесь MyStringEnumerationArray[x] - массив значений, которые нужно перебирать при помощи АС.
здесь MyStringEnumerationArray[x] - массив значений, которые нужно перебирать при помощи АС.
2. Описание допустимых для 2D АС значений. Для треугольника и параллелограмма были описаны зависимости двух координат, такие что АС был вынужден попадать только в вершины контура. Такие условия должны описываться в скрипте параметров, в 2Д скрипте необходимо пользоваться уже готовыми, требуемыми по логике значениями координат, строк, углов, массивов и т.д. Попробуйте поставить комменты на синие части строки и посмотреть как поведут себя АС.
values "X2" X1-AX*FSC,X1+AX*FSC,X1-BX*FSC,X1+BX*FSC
IF (X2=X1-AX*FSC) or (X2=X1+BX*FSC) then
values "Y2" Y1+FSC
endif
IF (X2=X1+AX*FSC) or (X2=X1-BX*FSC) then
values "Y2" Y1-FSC
endif
Extended 2: чтобы сделать перебор активным спотом произвольного заданного набора точек, необходимо в цикле проверять расстояние от АС до каждой точки набора, при заданной точности конечно, и менять координаты АС, только при попадании в "магнитную"(<E) область одной из точек.
3. Самый важный пожалуй здесь момент - использование следующего синтаксиса:Extended 2: чтобы сделать перебор активным спотом произвольного заданного набора точек, необходимо в цикле проверять расстояние от АС до каждой точки набора, при заданной точности конечно, и менять координаты АС, только при попадании в "магнитную"(<E) область одной из точек.
if GLOB_MODPAR_NAME = "sAng" then...
переменная GLOB_MODPAR_NAME - один из 3-х китов интерактивности GDL.
Данная строка позволяет скрипту "откликаться" на действия пользователя как через меню так и при редактировании на плане/в 3Д, посредством активных спотов, связанных с параметрами. GLOB_MODPAR_NAME - имя глобальной переменной, которая содержит имя последнего измененного пользователем параметра. Используя вышеуказанную строку GDL-скрипт позволяет писать по сути обработчики событий (в терминологии ООП). Используя связку из условий:
if GLOB_MODPAR_NAME = "имя_параметра" then...
if имя_параметра=значение_1 then...
endif
if имя_параметра=значение_2 then...
endif
endif
реализуется практически любое поведение объекта, его логика. На этом принципе построены различные GDL-объекты, с интерактивной логической нагрузкой - игра-пятнашки, и др.
4. Скрипт спецификаций. В данном объекте скрипт не разрабатывался, объект не представляет собой 3d объект, который можно осмечивать, не имеет компонентного состава(не состоит из других измеримых объектов - материалов, деталей). Но специфика объекта такова, что он должен как раз "закрывать" случай когда 3Д модель не будет построена(писал в INTRO п1.6.),
поэтому объект имеет параметры для правильного специфицирования с помощью ИК. Скрипт параметров при помощи условных выражений предоставит пользователю параметры ИК относящиеся только к выбранному типу маркера, таким образом, исключая возможность неправильного ввода:
! прячем ненужные для параллелограма параметры
if type="Параллелограм" then
HIDEPARAMETER "rad1s", "rad2s",
"snap_type", "spsp"
=======================================================================
=======================================================================
На этом все, скачать архив этой статьи, демо-видео и сам объект(версия для AC16) можно здесь: http://arch-grafika.rusfolder.net/files/34554085
следующая GDL тема:
"О целесообразности написания своего объекта, и его проектировании", или есть другие предложения?
К сожалению не удалось скачать по ссылке((
ОтветитьУдалитьув. dimdiad,
Удалитьфайлы размещены на файлообменном сервисе rusfolder, ссылка рабочая,
для скачивания файла необходимо просмотреть в течение 30 секунд рекламу спонсоров, по одной из ссылок, это мой спортивный интерес(понять и простить). Возможно проблема в том что у вас запрещены всплывающие окна.
Если это не решит проблему, советую погуглить по: не могу скачать с русфолдер...
http://arch-grafika.rusfolder.net/files/faq
УдалитьНесмотря на размер поста и позднее время суток всё же осилил. Интересный момент с графическим редактированием массива MyStringEnumerationArray[x]. Буду пробовать. Хотелось бы отработать простой универсальный макрос с функцией селектора:
ОтветитьУдалить-ввод>массив значений
-вывод>выбранное значение
Спасибо за детальное изложение.Вижу, что Вы хотели чуть разбавить текст `неофициальными`
комментами, но всё же пойду чуть отойду с кофе на кухне)))
Оч.классный объект в смысле уровня. Еще раз спасибо.
ОтветитьУдалитьСпасибо. Остался еще один момент описанный в Extended2, если не забуду в одном из след. постов напишу его реализацию.
УдалитьПривет, у меня есть вопросы по GDL.
ОтветитьУдалитькак можно с Вами связаться?
напишите мне пжлста письмо
moitilifon собака gmail.c0m
буду очень признателен.