Kalkulator, Technologia Maszyn

[ Pobierz całość w formacie PDF ]
K
ALKULATOR
G
EOMETRYCZNY
JAKO
NARZÊDZIE
RÊCZNE
I
W
PROCEDURACH
A
UTO
LISP-
U
alkulator Geometryczny, czyli Geomcal, to
program napisany w jêzyku C i do³¹czony do
AutoCAD-a. Poza zwyk³ymi funkcjami kal-
kulatora, znanymi z kalkulatorów elektronicz-
nych (a tak¿e ze szko³y), zawiera on szereg funkcji ge-
ometrycznych, pozwalaj¹cych na pobieranie informa-
cji wprost z narysowanych obiektów.
Opis dzia³ania wszystkich funkcji tego programu mo¿-
na znaleæ w dokumentacji dostarczanej wraz z progra-
mem. Tutaj ograniczymy siê do ogólnego ich omówienia
oraz podania prostych przyk³adów. W dalszym ci¹gu po-
damy sposób zastosowania tych funkcji w procedurach
AutoLISP-u. Zastosowanie funkcji Kalkulatora w proce-
durach AutoLISP-u znacznie skraca kod programu, czy-
ni¹c go bardziej czytelnym. Zapis wzorów jest zbli¿ony
do zwyk³ego, bez szaleñstwa wielokrotnych nawiasów.
Funkcje typowo geometryczne, np. wyznaczanie punktu
przeciêcia prostej z p³aszczyzn¹, znakomicie u³atwiaj¹ pro-
gramowanie. Postaramy siê pokazaæ to na kilku nieskom-
plikowanych przyk³adach. Jeli niektore z omówionych
poni¿ej procedur w³aczymy do zbiorów *.mnl i *.mnu
(gwiazdki zastêpuj¹ dowoln¹ nazwê), to mo¿emy uzyskaæ
³atwo dostêpne i bardzo przydatne narzêdzia menu.
Zacznijmy od spraw najprostszych. Jak nie znacie,
to pos³uchajcie.
Aby uruchomiæ Geomcal wybieramy Kalkulator w
menu rozwijalnym lub w menu myszy albo
Command:
piszemy
cal
. W procedurach pisanych w AutoLISP-
ie wprowadzamy liniê
(xload geomcal)
.
Wyra¿enia pisze siê po znaku zachêty, czyli
>>
Expression:
(w wersji PL:
>>
Wyra¿enie
)
i nie
pisze siê znaku równoci, tylko naciska klawisz EN-
TER
Ã
.
Przyk³ady obliczeñ arytmetycznych:
Mo¿na nadawaæ wartoci zmiennym, np.:
>> Expression
: a = 1.435
a nastêpnie u¿ywaæ tych zmiennych w dowolnych wzorach.
Wspó³rzêdne punktów i wektorów mo¿na zapisaæ
w dowolny sposób, jako wspó³rzêdne kartezjañskie, bie-
gunowe, walcowe lub sferyczne. Zapisuje siê je zawsze
w nawiasach kwadratowych. Mo¿na na nich wykonywaæ
wszystkie znane dzia³ania.
Przyk³ady (wyra¿enia piszemy oczywicie po
>>
Expression:
)
a)[4,6,7]+[120<120]
Ã
(-56.0 109.923 7.0)
b)[20,40,50]+[100<23,45]+[100<-20<-35]
Ã
(189.026 51.0565
37.6424)
c)[45,-12,48]*[125,234,-67]
Ã
-399.0
d)[12,5,-4.5]&[7,4,9]
Ã
(63.0 -139.5 13.0)
e)[45<50]*[20<-10]
Ã
450
f)[45<50]&[20<-10]
Ã
(0.0 0.0 -779.423)
g)[20<45]&[20<45,30]
Ã
(424.264 -424.264 0.0)
Przyk³ady a) i b) to dodawanie wektorów zapisanych
w ró¿nych formatach. Jak widaæ wynik otrzymujemy za-
wsze we wspó³rzêdnych kartezjañskich. Przyk³ady c) i d)
to iloczyn skalarny wektorów, a trzy ostatnie przyk³ady to
iloczyny wektorowe.
Bardzo wa¿n¹ spraw¹ jest odczytywanie punktów nale-
¿¹cych do narysowanych obiektów. Punkty mo¿na wskazy-
waæ stosuj¹c wszystkie tryby polecenia
OSNAP,
podaj¹c trzy
pierwsze litery nazwy trybu, czyli:
end, int, cen,
mid, ins, nea, nod, qua, per, tan, qui
.
Ponadto
cur
odczytuje wspó³rzêdne dowolnie wskazanego
punktu w lokalnym uk³adzie wspó³rzêdnych. Wartoæ wspó³-
rzêdnych ostatnio wskazanego punktu jest podstawiana pod
zmienn¹ systemow¹
LASTPOINT (@) AutoCAD-a
.
Mo¿na u¿yæ tych punktów w obliczeniach. Oto przyk³ady:
a) Znalezienie rodka ciê¿koci trójk¹ta
>> Expression:
(6.67^2.4 + 3.14*4.6)/5.1
Ã
21.4673
>> Wyra¿enie: 3.1*(12 + 6*2)
Ã
74.4
Command:
cal
Ã
>>Expression:
(end + end + end)/3
Ã
Prawid³owe wyra¿enie musi mieæ oczywicie tê
sam¹ liczbê nawiasów otwieraj¹cych, co zamykaj¹cych.
Wspomnia³em powy¿ej o szaleñstwie nawiasów. Po-
patrzmy na prosty wzór zapisany w trzech standardach:
Po wskazaniu trzech wierzcho³ków trójk¹ta otrzyma-
my wspó³rzêdne rodka ciê¿koci.
b) Rysowanie linii od punktu przesuniêtego o pewien
wektor od rodka ko³a.
x = (a*b+c)/d+ a/b+c/(d+a)
to znana nam wszystkim notacja wzoru;
(setq x (+ (/ (+ (* a b) c) d)(/ a b)(/ c (+ d a))))
która
w AutoLISP-ie wygl¹da trochê mniej czytelnie;
(setq x (cal (a*b+c)/d+ a/b+c/(d+a) ))
zapis z u¿yciem kalkulatora
przywraca jej zrozumia³¹ postaæ.
Command:
LINE
Ã
From point:
cal
Ã
>>Expression:
(cen+[60,45])
Ã
Wskazujemy na brzeg okrê gu, a linia zaczepia siê w punkcie przesuniê tym od rodka
okrê gu o [60,45].
To point:
Wskazujemy nastê pny punkt linii
Ã
.
W wyra¿eniach mo¿na stosowaæ funkcje geome-
tryczne (k¹ty podaje siê w stopniach) i inne, takie jak
exponent
exp
(l. rzeczywista), zamiana k¹tów z radia-
nów na stopnie
r2d
(kat), sta³a
p
pi, pierwiastek kwa-
dratowy
sqrt
(l. rzeczywista) itd.
Przyk³ady obliczeñ:
Uwaga: w ostatnim przyk³adzie przed
cal
widnieje
apostrof. Zapewnia on wykonanie obliczeñ bez przerwa-
nia dzia³ania polecenia
LINE
.
W procedurach jêzyka AutoLISP wyra¿enia obliczane
przy u¿yciu kalkulatora zapisuje siê wed³ug formatu:
(cal
wyra¿enie)
. Przeledmy kolejne przyk³ady (dla u³a-
twienia ledzenia programów w komentarzach u¿y³em pol-
>> Expression
: sin(30)+cos(60)
Ã
1
>> Wyra¿enie:
sqrt(23.345)*atan(0.5)+sqr(0.123*pi)
Ã
128.533
36
Kwartalnik
www.helion.com.pl/3d/index/3dindex.shtml
skich liter, ale nie w kodzie bo i tak w AutoLISP-ie u¿yæ
ich siê nie da).
ilp(p1,p2,pp1,pp2,pp3)
Punkt przeciêcia
linii danej punktami p1 i p2 z p³aszczyzn¹ wyznaczon¹
przez punkty pp1, pp2, pp3.
rot(pkt_obr, r_obr, k¹t)
Punkt otrzy-
many przez obrót punktu obracanego pkt_obr wokó³
rodka obrotu r_obr o k¹t k¹t.
Ponadto wielokrotnie zastosowano dodawanie
wspó³rzêdnych punktów za pomoc¹ kalkulatora, co
omówi³em wczeniej.
(defun c:srpr(/ p)
(prompt \nPunkt w srodku prostokata
\nWska¿ dwa naro¿a prostok¹ta tworzace przekatna )
(setq p (cal (end+end)/2))
(command _point p )
)
;;;punkt w rodku dowolnego trójk¹ta
(defun c:srtr(/ p)
(prompt \nPunkt w srodku prostokata \nWskaz naroza
trojkata )
(setq p (cal (end+end+end)/3))
(command _point p )
)
;Procedura rysowania prostok¹ta o wymiarach a*b z jednym
wierzcho³kiem w punkcie pkld
(defun c:prost(a b)
(command _pline pkld (cal pkld + [a,0]) (cal pkld
+ [a,b]) (cal pkld + [0,b]) _c)
)
;Punkt przeciêcia prostej pr1 pr2 z p³aszczyzn¹ wyznaczon¹
przez trzy punkty
;i przesuniêcie o dz w kierunku z.
(defun ilpm(pr1 pr2 dz)
(cal ilp(pr1,pr2,pz1,pz2,pz3)+[0,0,dz])
)
;Punkt na wysokoci h nad punktem pr.
(defun na_wys_h(pr h)
(cal(pr+[0,0,h])
)
;obrót punktu odleg³ego o wektor (a b) od punktu obrotu
pobr o kat alfa.
(defun rotal(pobr a b alfa)
(cal rot(pobr+[a,b],pobr,alfa))
)
;rysowanie linii przenikania komina z po³aci¹ dachow¹
(defun c:przen(/ pkld a b al h pz1 pz2 pz3 pz4 p1 p2 p3 p4
pk1 pk2 pk3 pk4)
(graphscr)
(setvar cmdecho 0)
(setvar osmode 0)
;³adowanie kalkulatora geometrycznego
(xload geomcal)
;wymazanie wszystkich obiektów z rysunku
(command _erase all )
(command _plan )
(command _color white)
(setq pkld (getpoint \nWska¿ lewy dolny punkt prostok¹ta:
)
a (getdist \nPodaj d³ugoæ prostok¹ta:
)
b (getdist \nPodaj wysokoæ prostok¹ta:
)
W kolejnej procedurze wykorzystamy funkcjê geome-
tryczn¹ Kalkulatora
ill(w1,w2,w3,w4)
. Wyznacza ona
punkt przeciêcia siê dwu prostych, okrelonych przez punk-
ty w1 i w2 (pierwsza prosta) oraz w2 i w3 (druga prosta).
rodek geometryczny wieloboku wyznacza punkt przeciê-
cia siê siecznych dwu s¹siednich boków.
;;;rodek dowolnego wieloboku foremnego lub prostok¹ta
(defun c:sr_wiel_f(/ p1 p2 p3 ps1 ps2 a1 a2 pa1 pa2 p)
(prompt \nPunkt w srodku wieloboku foremnego lub
prostokata \nWskaz trzy kolejne naroza )
; Wyznaczenie wspó³rzêdnych trzech kolejnych naro¿y
(setq p1 (cal end)
p2 (cal end)
p3 (cal end)
; Wspó³rzêdne rodków dwu s¹siednich boków
ps1 (cal (p1+p2)/2)
ps2 (cal (p2+p3)/2)
; K¹ty nachylenia boków
a1 (cal ang(p1,p2))
a2 (cal ang(p2,p3))
; Wyznaczenie dwu punktów le¿¹cych na kierunku prostopad³ym
do boków
pa1 (cal ps1+[50<(a1+90)])
pa2 (cal ps2+[50<(a2+90)])
; Wyznaczenie punktu przeciêcia dwu prostych - rodek.
p (cal ill(ps1,pa1,ps2,pa2))
)
(command _point p)
)
;;;pocz¹tek linii od punktu odleg³ego o wektor (a,b) od
koñca odcinka
(defun c:l_od_kl(/ a b pk p)
(prompt \nLinia zaczynajaca sie od punktu odleglego
od konca odcinka
o wektor (a,b) )
(initget 1)
(setq a (getdist \nOdl. w kierunku X )
b (getdist \nOdl. w kierunku Y )
)
(setq pk (cal end)
p (cal pk+[a,b])
)
(command _line p)
(princ \nTo point: )
(command pause)
)
)
;W poni¿ej wywo³anej procedurze wspó³rzêdne wierzcho³ków
prostok¹ta obliczono dodaj¹c
;odpowiednio d³ugoci boków do wspó³rzêdnych punktu pkld
wskazanego mysz¹.
(prost a b)
;ustawienie widoku
(command _vpoint 1,-1,1)
(command _zoom _all _zoom 0.5x)
(prompt \nPodaj wysokosci trzech punktow plaszczyzny
(nad wierzcholkami prostokata) :)
(command point pkld)
(setq z1 (getdist \n z1 = ))
(entdel (entlast))
(command point (cal pkld+[a,0]))
(setq z2 (getdist \n z2 = ))
(entdel (entlast))
(command point (cal pkld+[a,b]))
(setq z3 (getdist \n z3 = ))
(entdel (entlast))
(setq pz1 (cal pkld+[0,0,z1])
pz2 (cal pkld+[a,0,z2])
pz3 (cal pkld+[a,b,z3])
;Przyjêto dowoln¹ rzêdn¹ z punktu pz4 w celu wyznaczenia
prostej pionowej narysowanej
;z wierzcho³ka prostok¹ta.
pz4 (cal pkld+[0,b,50])
A oto inny przyk³ad, w którym zastosowano kilka funk-
cji kalkulatora, co bardzo u³atwi³o programowanie i skróci³o
kod programu. Jest to program wyznaczaj¹cy liniê przeni-
kania prostopad³ocianu z p³aszczyzn¹. Typowym przyk³a-
dem na zastosowanie tego programu mo¿e byæ wyznacze-
nie linii przenikania komina z po³aci¹ dachow¹.
Zastosowa³em nastêpuj¹ce funkcje geometryczne kal-
kulatora geometrycznego:
padziernik listopad grudzieñ
nr 4/1997 37
;Wyznaczono punkt przeciêcia prostej przechodz¹cej przez
punkty
;pkld + [0,b] i pz4 z p³aszczyzn¹ wyznaczon¹ przez punkty
pz1, pz2 i pz3.
pz4(cal ilp(pkld+[0,b],pz4,pz1 pz2,pz3))
)
(command 3dface pz1 pz2 pz3 pz4 )
(prompt \nNarysuj teraz drugi prostokat wewnatrz poprzednio
narysowanego: )
(setq pkld (getpoint \nWskaz lewy dolny punkt prostokata:
)
a (getdist \nPodaj d³ugosc prostokata: )
b (getdist \nPodaj wysokosc prostokata: )
al (getangle \nPodaj kat obrotu: )
;K¹t w funkcji getangle podaje siê w stopniach, a funkcja
przelicza go na radiany, dlatego
;nastêpna linia przelicza go z powrotem na stopnie.
al (cal al*180/pi))
h (getdist Podaj wysokoæ komina: )
)
(command _color yellow)
(prost a b)
(command _rotate (ssget pkld) pkld al)
;Wskazano obiekt (prostok¹t) za pomoc¹ punktu pkld
nale¿¹cego do tego prostok¹ta.
;Nadano prostok¹towi wysokoæ h.
(command _change (ssget pkld) _p _t h )
;Obrót punktów naro¿nych prostok¹ta o k¹t al.
(setq p2 (rotal pkld a 0 al)
p3 (rotal pkld a b al)
p4 (rotal pkld 0 b al)
)
;Obliczenie wspó³rzêdnych górnych wierzcho³ków komina.
(setq pk1 (na_wys_h pkld h)
pk2 (na_wys_h p2 h)
pk3 (na_wys_h p3 h)
pk4 (na_wys_h p4 h)
)
;Obliczenie wspó³rzêdnych punktów przenikania komina z
po³aci¹ dachow¹.
;Przesuniêcie w górê zwiêksza widocznoæ tej linii.
(setq p1 (ilpm pkld pk1 2)
p2 (ilpm p2 pk2 2)
p3 (ilpm p3 pk3 2)
p4 (ilpm p4 pk4 2)
)
;Narysowanie linii przenikania.
(command _line p1 p2 p3 p4 _c)
(command zoom _all)
(command _color _white)
(command shadedge 2 shade)
)
W powy¿szym programie zdefiniowano równie¿
krótkie procedury z zastosowaniem funkcji Kalkulato-
ra. Mo¿na je oczywicie u¿yæ w innych programach
lub przy rysowaniu. W tym ostatnim przypadku najle-
piej zmodyfikowaæ menu rozwijalne i umieciæ w nim
te procedury.
Przedstawmy jeszcze metodê rysowania odcinka
prostopad³ego do danego odcinka.
Skorzystamy z funkcji Kalkulatora
vec1(w1,w2)
,
obliczaj¹cej wspó³rzêdne wektora jednostkowego na
kierunku punktów w1 i w2. Zdefiniujmy najpierw wek-
tor jednostkowy normalny do kierunku wyznaczonego
przez punkty w1 i w2.
;Jednostkowy wektor normalny, prostopad³y do odcinka
;danego przez punkty w1 i w2
(defun nor1(w1 w2 / a b v)
(setq v (cal vec1(w1,w2))
a (cadr v)
b (* -1 (car v))
)
(list a b)
)
Jest to zapewne nastêpne narzêdzie, które warto wpisaæ do menu.
;Odcinek normalny do wskazanego odcinka
;dw dlugoæ odcinka.
;Strona, po której zostanie narysowany odcinek, jest zale¿na
od kolejnoci wskazania punktów
;odcinka i od znaku wartoci dw.
(defun c:odc_pp(/ w1 w2 dw st p1 p2)
(xload geomcal)
(setvar cmdecho 0)
(graphscr)
(command _osnap end)
(setq w1 (getpoint \nWskaz koniec odcinka: )
w2 (getpoint \nWskaz drugi koniec odcinka:
)
dw (getdist \nDlugoæ odcinka normalnego: )
)
;Wybór punktów na odcinku - tryb int mo¿na wybraæ, gdy
jakie odcinki przecinaj¹ siê ze sob¹
(initget 1 end int nea mid)
(setq st (getkword \nPodaj tryb wyboru punktu odcinka
<end/int/nea/mid>))
(command _osnap st)
(setq p1 (getpoint \nWskaz punkt na odcinku: )
;Obliczamy wektor normalny do odcinka, a nastêpnie
po³o¿enie koñca odcinka (punkt p2)
p2 (nor1 w1 w2)
p2 (cal p1+p2*dw)
)
(command _line p1 p2 )
(command _regen)
)
A oto rysunek uzyskany w wyniku dzia³ania programu:
Przypomnijmy sobie, ¿e wyznaczalimy poprzednio
dwusieczne boków, by otrzymaæ rodek wieloboku lub
prostok¹ta, a dwusieczna to oczywicie odcinek prosto-
pad³y do danego boku. Oznacza to, ¿e mo¿na by zmo-
dyfikowaæ procedurê sr_wiel_f stosuj¹c procedurê nor1
do obliczania wektorów normalnych. Jak widaæ, wszy-
stko mo¿na zrobiæ na wiele ró¿nych sposobów.
Stefan wiszczowski
swiszcz@usk.pk.edu.pl
Kraków
38
Kwartalnik
www.helion.com.pl/3d/index/3dindex.shtml
[ Pobierz całość w formacie PDF ]
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • klobuckfatima.xlx.pl