Eli mitenkäs sais piirrettyä käyrän pictureboxiin? Pictureboxi pitää ensin Clearata mustaksi, jonka jälkeen sinne piirretään punainen käyrä. Mitenkä tuo onnistuisi helpoiten?
onPainttiin e.Graphics.DrawCurve(Pens.Red, points)
Tai siis enemmänkin ehkä monimutkainen käyräkaavio.
Pohja:
'Formilla PictureBoxi PicCurve Public Class frmCurve Inherits System.Windows.Forms.Form Dim curvePoints(25) as System.Drawing.Point Dim g as Graphics Private Sub frmCurve_Load(ByVal sender As System.Object, ByVal e as EventArgs) Handles MyBase.Load Me.PicCurve.Image = New Bitmap(Me.PicCurve.Height, Me.PicCurve.Width) g = Graphics.FromImage(Me.PicCurve.Image) g.Clear(Color.Black) curvePoints(0) = New Point(200, 500) 'Esim. curvePoints(1) = New Point(500, 300) 'jne... DrawCurve(g) End Sub Public Sub DrawCurve(ByVal g as Graphics) Dim oldPoint, newestPoint As Point oldPoint = New Point(0, 0) 'Aloituskoordinaatit For i = 0 to curvePoints.Length newestPoint = curvePoints(i) If Not newestPoint.X <= oldPoint.X And newestPoint.Y <= oldPoint.Y Then MsgBox("ERROR", 16, "ERROR") 'Käyrä ei saa kääntyä takaisin! Exit Sub End If g.DrawLine(Pens.Red, oldPoint, newestPoint) Next End Sub End Class
(ei testattu)
Siis nyt en ihan ymmärrä miksi kysyit "helpointa tapaa" ja sitten implementoit itse, kun graphicsissa on (.Net Framwork 4:ssä ainakin) tuo mainitsemani DrawCurve suoraan? Tekee vielä määriteltyjen pisteiden kautta kulkevan SPLinen eli käyrän eikä tuollaista monikulmiota kuten oma rutiinisi.
Tosin ilmeisesti halusit jonkun funktion kuvaajan etkä varsinaisesti käyrää päätellen tuosta "ei saa kääntyä takaisin" kommentista.
Siis haluaisin sellaisen käyrän kuten esimerkiksi on Tehtävienhallinnassa Suorituskyky -välilehdellä. Mutta ehkä keksinkin jo... Testaan kohta.
Siis näin?
For i = 0 to curvePoints.Length-2 g.DrawLine(Pens.Red, curvePoints(i), curvePoints(i+1)) Next
edit: Korjattu -2
User137 kirjoitti:
Siis näin? ...
Tuossa varmaan kannattaa muistaa pitää huolta, että pisteitä on parillinen määrä, jotta tuo i+1 ei aiheuta hankaluuksia? Löytyyköhän .NET:ille polyline funktiota?
Miksi parillinen määrä? Haittaako tuossa parittomuus oikeasti mitään?
Ei, yhtä huonosti toimii parillisellakin määrällä.
Sen pitäisi olla: to curvePoints.Length - 2
'näin Public Class frmCurve Inherits System.Windows.Forms.Form Dim curveStates(4) As System.Drawing.Point Dim g As Graphics Private Sub frmCurve_Load(ByVal sender As System.Object, ByVal e as EventArgs) Handles MyBase.Load Me.BackgroundImage = New Bitmap(Me.PicCurve.Height, Me.PicCurve.Width) g = Graphics.FromImage(Me.BackgroundImage) g.Clear(Color.Black) curveStates(0) = 86 curveStates(1) = 286 curveStates(2) = 386 curvestates(3) = 486 curveStates(4) = 15 DrawCurve(g) End Sub Public Sub DrawCurve(ByVal g as Graphics) Dim oldPoint, newestPoint As Point oldPoint = New Point(0, 0) 'Aloituskoordinaatit For i = 0 to curveStates.Length - 1 newestPoint = New Point(i * 50, curveStates(i)) g.DrawLine(Pens.Red, oldPoint, newestPoint) oldPoint = newestPoint Next End Sub End Class
ErroR++ kirjoitti:
Public Sub DrawCurve(ByVal g as Graphics) Dim oldPoint, newestPoint As Point oldPoint = New Point(0, 0) 'Aloituskoordinaatit For i = 0 to curveStates.Length - 1 newestPoint = New Point(i * 50, curveStates(i)) g.DrawLine(Pens.Red, oldPoint, newestPoint) Next End Sub
Pitikös tuossa piirtää aina uusi suora nolla pisteestä, vai unohditko päivittää OldPoint muuttujan arvoa silmukassa?
Täytyy muuten sanoa, että omaa silmää Component Pascalin syntaksi miellyttää VB:tä enemmän...
Mielestäni tuossa tilapäiseen muuttujaan laittamisessa ei muutenkaan ole mitään järkeä verrattuna taulukkoarvojen käyttämiseen suoraan.
Jos tuo olisi edes tehty foreach -silmukassa, niin jotain perustetta tuollaiselle voisi olla.
Eli joko
g.DrawLine(Pens.Red, New Point(0, 0), curvePoints(0)) 'Jos oikeasti tarvitaan?? For i = 0 to curvePoints.Length-2 g.DrawLine(Pens.Red, curvePoints(i), curvePoints(i+1)) Next
tai
Dim oldPoint = New Point(0, 0) 'Aloituskoordinaatit For Each point In curvePoints g.DrawLine(Pens.Red, oldPoint, point) oldPoint = point Next
Mutta ei tuollaista epäsikiötä.
Tai ehkä olemme väärässä ja tarkoitus oli sittenkin piirtää kaikki viivat lähtemään 0,0:sta.
jalski kirjoitti:
Täytyy muuten sanoa, että omaa silmää Component Pascalin syntaksi miellyttää VB:tä enemmän...
No ei kai se mikään ihme ole, kun VB.Net on Basicin näköiseksi väännettyä C#:a :D Itsekin koodaan paljon mieluummin C#:lla vaikka omaankin hyvin pitkän basic-taustan.
kumpi on ihan oikein - ja miksi?
(kysyn kun kumpikin esiintyy)
1.
"For i = 0 to curvePoints.Length-2"
2.
"For i = 0 to curvePoints.Length-1"
Ensimmäinen on oikein, koska curvePoints
:n indeksit alkavat nollasta eli viimeinen on curvePoints.Length-1
. Käyrän viimeinen osa taas on viiva toiseksi viimeisestä pisteestä viimeiseen.
Sehän riippuu käytetäänkö siellä curvePoints(i+1):tä vai vain curvePoints(i):tä.
Jos käytetään curvePoints(i+1):tä, niin silloin on oikein:
For i = 0 to curvePoints.Length-2
Jos käytetään vain curvePoints(i):tä, niin silloin on oikein:
For i = 0 to curvePoints.Length-1
Jos sulla on 3 pistettä ja niistä piirretään graafi niin se tarkottaa kahta viivaa. Eli viivojen määrä on curvePoints.Length-1, mutta kun aloitetaan nollasta eikä ykkösestä niin väli on 0 to curvePoints.Length-2. Korjasin oman virheen.
Joo, mutta ErroR+:n virityksessä on yksi piste, (0,0), josta piirretään viivat kaikkiin pisteisiin. Siinä tapauksessa se -1 on ihan oikein.
Viitaten siis tähän "on esiintynyt kahta tapaa, kumpi on oikein?"
Sinänsä mielestäni ei lupaa hirveän hyvää koodaamiseen jos ei oikeaa vaihtoehto kuhunkin tilanteeseen saa pähkäiltyä itse muutaman minuutinkaan miettimisellä.
Heippa taas!
käy se For...Next silmukassa ilman 'miinusteluakin'...
For i As Integer = 0 To CurvePoints.GetUpperbound(0) Try g.DrawLine(Pens.Red, CurvePoints(i), CurvePoints(i + 1)) Catch ex As Exeption End Try Next
neau33 kirjoitti:
käy se For...Next silmukassa ilman 'miinusteluakin'...
For i As Integer = 0 To CurvePoints.GetUpperbound(0) 'jne. Next-Nea-
Jeps... Tässä tosin oli bonuksena tilanne, että piti varmistaa arrayn indeksin pysyvän rajoissa ( curvePoints(i+1) ei siis saisi mennä yli ).
Aihe on jo aika vanha, joten et voi enää vastata siihen.