Moi
Olen nyt piirtämässä visual basic 6:lla kappaletta. Kappale koostuu osista, jotka ovat kiinni toisissaan, mutta ne piirretään eri aikaan. Eli esimerkiksi ensimmäisenä piirrätän nappia painamalla lähtötiedoista suorakaiteen muotoisen palan, sen perään piirretään kaksi kaaren pätkää, jotka kuvaavat kulmaa(esimerkiksi 23 astetta). Uusien tietojen syöttämisen ja seuraavan napin painalluksen jälkeen olisi tarkoitus piirtää seuraava suorakaiteen muotoinen palanen niiden kaaren pätkien jatkoksi. Ja sitten taas seuraavat kaaren pätkät piirretyn suorakaiteen perään jne. Jolloin lopulta muodostuu yhtenäinen kappale, jossa on suorakaiteen muotoisia paloja eri kulmissa ja kaaren pätkiä kuvaamassa taitosta kappaleessa.
Nyt olen yrittänyt piirtää kyseistä kappaletta Line ja circle metodilla. Ja olen onnistunutkin piirtämään muutamia suorakulmioita ja kaaren pätkiä. Ongelmanani on kuitenki se, että kyseisellä tavalla joudun kirjoittamaan hirveästi koodia erillaisten kulma mahdollisuuksien takia. Ja mitä eteemmäs kappaleessa pääsee, sitä enemmän pitää laskea mikä on se todellinen kulma muuttumattomaan koordinaatistoon nähden.
Onko siis olemassa jokin tapa esimerkiksi kääntää koordinaatistoa picturepoxissa? Saako suorakaiteen muotoisen palikan piirrettyä jotenkin kaltevaan asentoon? Vai onko olemassa jokin apuneuvo kyseisen mallisen kappaleen piirtämiseen.
Jos jokin jäi epäselväksi kysy.
Terveisin Veikko
Kuvaboxin ja formin koordinaatistoa ei voi kääntää vinoon, ainoastaan suunnan voi vaihtaa vastakkaiseksi ja origon paikkaa ja skaalausta muuttaa. Koordinaatiston kierto on siis hoidettava koodaamalla. Vinon suorakaiteen voi piirtää neljällä Line-käskyllä eli jokainen sivu erikseen koska Line-käskyssä B piirtää vain vaaka- ja pystyviivoja. Jos kuviot on täytettävä värillä on käytettävä API-kutsua ExtFloodFill, josta löytyy esimerkki Antin VB-oppaasta. Onko tarkoitus piirtää jonkinmoinen putki tai väylä vai mikä? Leveätä viivaa voi piirtää myös asettamalla DrawWidth riittävän suureksi.
Juuri noin olen nyt tehnytkin: koodannut koordinaatisto muutokset, piirtänyt suorakaiteen neljällä line käskyllä. Olen kokeillut paksumpaa viivaa, mutta tullut siihen tulokseen että saan hienomman lopputuloksen, jos piirrän erillisistä viivoista.
Kyseessä on sellainen taivutettu metallilatta. Esimerkiksi kuparista 5 * 30 latta taivutetaan normaali tai sivuväärään suuntaan. Sitten siitä pitäisi piirtää kuva :)
Kiitos setä vastauksesta mutta ei auttanut hirveästi.
Terveisin Veikko
Lähinnä täytyy ihmetellä tuota, että "mitä eteemmäs kappaleessa pääsee, sitä enemmän pitää laskea"? Luulisi että melko helpolla laitat kappaleesi 3D koordinaatiston vektoreihin ja käännät katselukulman kertomalla sopivalla yksikkömatriisilla.
Oletko piirtämässä 3D- vai 2D-kuvaa. Ymmärsin että 2D. Jos 2D riittää, voit kehitelä vinon suorakaiteen piirtorutiinin, jossa parametreina alkupiste, suunta ja pituus. Leveys taitaa olla vakio. Uudeksi alkupisteeksi tulee äskeisen piirron päätepiste. vastaavasti toinen rutiini kaarien piirtoon. Suunta ja pituus voidaan osoittaa hiirellä ja esim. vasemmalla napilla suorakaide ja oikealla kaari tai jokin muu valinta. Suorakaiteen kohdalla taitaakin suunta määräytyä edellisen kaaren mukaan. Kaaressa voi osoittaa kaaren päätepisteen, jolloin kaaren sädekin tulee määrätyksi.
No niin Grez, nyt kuullostaa asialta!
Tajuan matemaattisesti mitä ajat takaa. Mutta mitä tuo tarkoittaa koodin kannalta?
Sedälläkin tuntuu olevan asiaa. 2D kuva on se mitä haen koska luulen että se on helpompi kuin 3D. 3D kuvan jos tekisin, kusisin samantien purkillisen hunajaa.
Piirtorutiinia suorakaiteille ja kulmille olen juuri parhaillani kehittämässä. Kehittelen sitä ja jos sen tiimoilta tulee kysyttävää kysyn, mutta nyt lähinnä halusin vastausta kysymykseen, että onko tapani käsitellä ongelmaa oikeanlainen(Circle, Line, koordinaatiston kääntö koodilla, jne.).
Piirrettävänä olevan kappaleen tiedot saadaan käyttäjän syöttäminä: esimerkiksi kaarenpätkän säde ja kulma sekä suorakaiteen pituus, leveys on vakio.
Juuri Line- ja Circle-käskyillä, mutta en kiertäisi koordinaatistoa vaan suuntakulma tulisi parametrina piirtorutiineihin. Jos data syötetään numeroina, kannattaa muutkin piirtokomennot syöttää näppäimillä eikä käyttää hiirtä lainkaan. Esim. tyyliin:aluksi annetaan alkupiste, alkusuunta ja leveys. Seuraavaksi määrätään piirretäänkö suora vai kaari. Sen jälkeen suorasta annetaan pituus, kaaresta säde ja kulma tai keskiviivan pituus ja kulma. Jotenkin näin sitä itse kehittelisin.
Joo no siis eihän 3D ja 2D systeemissä ole muuta eroa kuin että 3D-systeemissä on 3 lukua ja 2D-systeemissä 2 lukua. Eli toki sen voi pistää 2D koordinaatteina 2 yksikön vektoreihin ja kertoa 2*2 kokoisella matriisilla. Ajattelin vaan että halusit saada siihen jonkinlaisen perspektiivin myös, jolloin on loogisempaa kääntää 3D-avaruudessa ja laskea perspektiivi z-koordinaatin perusteella.
Tosin ainakin 3D käännettyjen kaarien mallintaminen circle-käskyllä voi olla vaikeaa.
Moro Grez
Kiitti taas valaistuksesta, mutta en oikein tajua koodin kannalta tota sinun matriisilla kertomista! Mitä se on? pistätkö esimerkin jos vain voit.
Joo circle käskyllä jos tekee 3D mallin niin kusen ämpärillisen hunajaa!
Matriisin avulla kierrot saadaan esitettyä näppärästi. Jos tason vektoria v=[v_x v_y]^T halutaan kiertää origon ympäri a radiaania, uuden koordinaatit saadaan matriisitulosta
[v_x']=[cos a -sin a][v_x]
[v_y'] [sin a cos a][v_y].
Kaikki tason kierrot voidaan palauttaa tähän kiinnittämällä origoksi kiertopiste.
Onkohan VB6:ssa matriisioperaatioita ?
Joko keksit ratkaisun Veikko? Kiinnosti tehtävä sen verran että sohlasin oman ratkaisun, noin parisataa riviä. Hiirellä säätäen kaikki jolloin on helpompi testailla. Voin laittaa koodin tänne jos kiinnostaa.
Moi
Tein sitä omaa versiotani mutta en saanut siitä puristettua sellaista yleistä mallia joka sopisi monimutkaisen kappaleen piirtämiseen. Yhden tavan keksin eilen ja sitä olisi koitettava tänään.
Jos setä laitat niin olen todella kiitollinen on kiva nähdä miten olet asiaa mietiskellyt.
terveisin Veikko
Toiminta lyhyesti:
1. Valitaan aloituspiste painamalla hiiripainike alas (vasen tai oikea) sekä valitaan aloitussuunta ja leveys vetämällä hiirtä haluttuun suuntaan nappi painettuna. Reunaviiva piirtyy samalla osoittaen leveyden ja suunnan. Kun säätö on kohdallaan vapautetaan painike.
2. Valitaan vasemmalla painikkeella suorakaiteen pituus tai oikealla painikkeella sektoriraidan pituus ja kulma kuten edellä raahaamalla.
3. Toistetaan kohtaa 2 ja lopetus painamalla hiiren keskimmäistä nappia jonka jälkeen voi piirtää toisen kuvion. Ruudun tyhjennys painamalla C-kirjainta.
Option Explicit Dim i As Integer, j As Integer Dim px() As Single, py() As Single Dim x0 As Single, y0 As Single Dim r As Single, k As Single Dim x1 As Single, y1 As Single Dim x2 As Single, y2 As Single Dim l As Single, lx As Single, ly As Single Dim s As Single, ro As Single Dim d As Single, pii As Single Dim si As Single, co As Single Dim dx As Single, dy As Single Dim a1 As Single, a2 As Single 'kaaren alku- ja loppukulma Dim a0 As Single, xe As Single, ye As Single Dim c As Long 'piirtoväri Private Sub Form_KeyUp(KeyCode As Integer, Shift As Integer) If KeyCode = vbKeyC Then i = 0: Cls End If End Sub Private Sub Form_Load() ReDim px(0), py(0) Caption = "Alkupiste" pii = 3.14159265 End Sub Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) DrawMode = 7 'kuminauhatila c = &HFFFF& 'piirtovärin komplementti If i = 0 Then px(i) = X: py(i) = Y 'aloituspiste Caption = "Suunta ja leveys" x1 = X: y1 = Y x2 = X: y2 = Y PSet (X, Y), c Else dx = X - px(i - 1) dy = Y - py(i - 1) If Button = 1 Then 'suorat Caption = "Suorakaiteen pituus" sarvot suorat ElseIf Button = 2 Then 'kaaret Caption = "Sektoriraidan pituus ja kaarevuus" kulma If k = s Then 'säde ääretön => suora Else r = l / Sin(s - k) 'kaaren säde If Abs(r) < d / 2 + 5 Then r = Sgn(r) * (d / 2 + 5) karvot Line (X - d * Cos(a0) / 2, Y - d * _ Sin(a0) / 2)-Step(d * Cos(a0), d * Sin(a0)), c kaaret xe = X: ye = Y End If End If End If End Sub Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) If i = 0 Then If Button = 1 Or Button = 2 Then 'säädetään leveys ja aloitussuunta Line (x1, y1)-(x2, y2), c d = (Y - py(i)) / 2 x1 = px(i) + d x2 = px(i) - d d = (X - px(i)) / 2 y1 = py(i) - d y2 = py(i) + d Line (x1, y1)-(x2, y2), c End If Else dx = X - px(i - 1) dy = Y - py(i - 1) Select Case Button Case 1 'suorat suorat 'pyyhitään edelliset sarvot 'uudet arvot suorat Case 2 'kaaret kulma If k = s Then 'säde ääretön => suora Else Line (xe - d * Cos(a0) / 2, ye - d * _ Sin(a0) / 2)-Step(d * Cos(a0), d * Sin(a0)), c kaaret ro = l / Sin(s - k) 'kaaren säde If Abs(ro) > d / 2 + 5 Then r = ro karvot Line (X - d * Cos(a0) / 2, Y - d * _ Sin(a0) / 2)-Step(d * Cos(a0), d * Sin(a0)), c 'poikkiviiva kaaret xe = X: ye = Y End If End If End Select End If End Sub Private Sub Form_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single) DrawMode = 13 'piirtotila c = 0 'piirtoväri musta If i = 0 Then Line (x1, y1)-(x2, y2), c 'alkureuna Caption = "Vasen painike: suora, oikea: kaari" dy = Y - py(i): dx = X - px(i) If dx > 0 Then s = Atn(dy / dx) 'suunta ElseIf dx < 0 Then s = pii + Atn(dy / dx) Else s = pii / 2 * Sgn(dy) End If d = Sqr(dx * dx + dy * dy) 'leveys If d = 0 Then 'virhe Cls Exit Sub End If si = dy / d: co = dx / d 'sin ja cos, tarvitaan myöhemmin Else If Button = 1 Then 'suorakaide suorat x1 = x1 + lx: y1 = y1 + ly 'uudet päätepisteet x2 = x2 + lx: y2 = y2 + ly px(i) = px(i - 1) + lx 'taulukkopiste py(i) = py(i - 1) + ly ElseIf Button = 2 Then 'sektoriraita kaaret dx = d * Cos(a0) / 2: dy = d * Sin(a0) / 2 x1 = X - dx: x2 = X + dx y1 = Y - dy: y2 = Y + dy Line (x1, y1)-(x2, y2) 'poikkiviiva s = 2 * k - s 'suunta If s > 3 * pii / 2 Then s = s - 2 * pii If s < -pii / 2 Then s = s + 2 * pii si = Sin(s): co = Cos(s) px(i) = X: py(i) = Y Else i = 0: Exit Sub End If End If i = i + 1 ReDim Preserve px(i), py(i) End Sub Private Sub Form_Resize() Me.ScaleMode = 3 Me.ScaleHeight = -Abs(Me.ScaleHeight) 'origo vasemmalle alas Me.ScaleTop = Abs(Me.ScaleHeight) End Sub 'suorien komponentit Sub sarvot() l = dx * co + dy * si lx = l * co ly = l * si End Sub 'suorakaiteen piirto Sub suorat() Dim cx As Single, cy As Single Line (x1, y1)-Step(lx, ly), c 'suora cx = CurrentX: cy = CurrentY Line (x2, y2)-Step(lx, ly), c 'toinen suora Line -(cx, cy), c End Sub Sub kaaret() Circle (x0, y0), r + d / 2, c, a1, a2 Circle (x0, y0), r - d / 2, c, a1, a2 End Sub 'kaaren kulman laskeminen Sub kulma() l = Sqr(dx * dx + dy * dy) / 2 If dx > 0 Then k = Atn(dy / dx) ElseIf dx < 0 Then k = pii + Atn(dy / dx) Else k = Sgn(dy) * pii / 2 End If End Sub 'kaarien arvot Sub karvot() x0 = px(i - 1) + r * si y0 = py(i - 1) - r * co If r > 0 Then a1 = 2 * k - s + pii / 2 a2 = s + pii / 2 a0 = a1 Else r = -r a2 = 2 * k - s + 3 * pii / 2 a1 = s + 3 * pii / 2 a0 = a2 End If Do While a1 > 2 * pii a1 = a1 - 2 * pii Loop Do While a2 > 2 * pii a2 = a2 - 2 * pii Loop If a1 < 0 Then a1 = a1 + 2 * pii If a2 < 0 Then a2 = a2 + 2 * pii End Sub
Hieno on kuin helvetti :)
Ennen kuin tutustun enempää, haluan kokeilla omaa versiotani, jos siitä olisi johonkin. Kiitos vaan, ainakin tuli todistettua, että tuollaisen piirtäminen on täysin mahdollista.
Ilmoittelen edistymisestäni...
Terveisin Veikko
Moi
Sain viimeisteltyä oman versioni tästä latan piirtämisestä. Ja hienosti tuntuu toimivan. Kiitos vain kaikille asiaan sotkeutuneille!
Kuitenkin yksi mutta! Nyt piirrettävä "mato" saattaa mennä jossain kohdassa ulos pictureboxista. Onko mahdollista että piirtää toiseen Pictureboxiin ja sitten sen saisi tulostettua/printattua keskelle toista kuvaa kokonaan näkyviin ja tietysti mahdollisimman isolla suurennoksella.
Nykyisin määrittelen skaalan Pictureboxille ensimmäisen suoran mukaan. Eli jos ensimmäinen suora on lyhyt saattaa loput pätkät mennä jo pois kuvasta.
Mikä neuvoksi?
Ajattelin ,että voisikohan CurrentX ja CurrentY tietoja käyttää hyväkseen, koska nehän kertovat missä suurimmat piirretyt arvot ovat.
Terveisin Veikko
Tuota ongelmaa varten tallensin tietyt pisteet taulukkoon jotta kuvion voi piirtää uudelleen. Jos muutat skaalausta, kuvio ei muutu kuin piirtämällä se uudelleen tai zoomaamalla esim PaintPicture-metodilla mikä taas ei aina ole hyvä keino. Eli paras tapa on tallentaa syötetty data niin että kuvio on mahdollista uudelleenpiirtää. Näin siihen voi myös lisätä muokkausmahdollisuuden eli voi jotain kohtaa kuviossa muuttaa tarvitsematta syöttää kaikkea dataa uudelleen.
Aihe on jo aika vanha, joten et voi enää vastata siihen.