Fault noise on hyvä, mutta hidas tapa luoda kaunista kohinaa.
Algoritmi toimii näin:
1) Vedetään alueen läpi viiva.
2) Kelataan jokainen pikseli ja trkistetaan kummalla "puolella" viivaa se on.
3) Riippuen puolesta, joko tummennetaan tai vaalennetaan sitä.
4) Toistetaan tätä monta kertaa. (tässä koodivinkissä 500)
Älkää pelästykö jos ohjelma ei tee mitään. Laskemisessa kestää todennäköisesti useita minuutteja. Itselläni meni aikaa 1 minuutti 31 sekunttia(1.8 ghz).
Tulos on odottamisen arvoinen, ainakin omasta mielestäni
Public Class frmNoise2 Inherits System.Windows.Forms.Form Dim b As Bitmap #Region " Windows Form Designer generated code " Public Sub New() MyBase.New() 'This call is required by the Windows Form Designer. InitializeComponent() 'Add any initialization after the InitializeComponent() call End Sub 'Form overrides dispose to clean up the component list. Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then If Not (components Is Nothing) Then components.Dispose() End If End If MyBase.Dispose(disposing) End Sub 'Required by the Windows Form Designer Private components As System.ComponentModel.IContainer 'NOTE: The following procedure is required by the Windows Form Designer 'It can be modified using the Windows Form Designer. 'Do not modify it using the code editor. Friend WithEvents picSurface As System.Windows.Forms.PictureBox <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() Me.picSurface = New System.Windows.Forms.PictureBox Me.SuspendLayout() ' 'picSurface ' Me.picSurface.Location = New System.Drawing.Point(0, 0) Me.picSurface.Name = "picSurface" Me.picSurface.Size = New System.Drawing.Size(384, 344) Me.picSurface.TabIndex = 0 Me.picSurface.TabStop = False ' 'frmNoise2 ' Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13) Me.ClientSize = New System.Drawing.Size(384, 342) Me.Controls.Add(Me.picSurface) Me.Name = "frmNoise2" Me.Text = "Noise2" Me.ResumeLayout(False) End Sub #End Region Private Sub frmNoise2_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim i As Integer Dim x, y As Integer Dim bi As New Bitmap(picSurface.Width, picSurface.Height) Dim g As Graphics Randomize() g = Graphics.FromImage(bi) g.Clear(Color.FromArgb(0, 0, 125)) g.Dispose() Dim d As Double = Math.Sqrt(200 * 200 + 200 * 200) For i = 1 To 500 ' arvotaan suora, joka puolittaa alueen Dim v As Double = Rnd() * 2 * Math.PI Dim a As Double = Math.Sin(v) Dim b As Double = Math.Cos(v) ' c:stä saadaan arvottu numero -d/2 ja d/2 väliltä Dim c As Double = Rnd() * d - d / 2 For x = 1 To 200 For y = 1 To 200 ' tarkistetaan, kummalla puolella viivaa piste on If (a * x + b * y - c > 0) Then ' kirkastetaan Dim clr As Integer clr = bi.GetPixel(x, y).B clr += 3 If clr > 255 Then clr = 255 bi.SetPixel(x, y, Color.FromArgb(0, 0, clr)) Else ' tummennetaan Dim clr As Integer clr = bi.GetPixel(x, y).B clr -= 3 If clr < 0 Then clr = 0 bi.SetPixel(x, y, Color.FromArgb(0, 0, clr)) End If Next Next Next picSurface.BackgroundImage = bi End Sub End Class
Koodista on poistettu paha bugi.
Binäärii?
Visual Basic 5 ei oikein tunnista tuota Class-sanaa. Pitäisikö sen tunnistaa?
Ei. Tämä on VB.NET:lle. Luokat ja periytyminen ovat yksi VB.NET:n uusista ominaisuuksista, joita muut vb:t eivät tue.
tuo osoite http://koti.mbnet.fi/koodaaja/jotaki/Noise2.exe ei toimi.
Toimiipas.
Eipäs toimi
peki kirjoitti:
Älkää pelästykö jos ohjelma ei tee mitään. Laskemisessa kestää todennäköisesti useita minuutteja. Itselläni meni aikaa 1 minuutti 31 sekunttia(1.8 ghz)
17 vuotta myöhemmin meni 7 sekuntia (3,6 GHz). Huomaa hyvin, että pelkät gigahertsit ei ratkaise.
Sinänsä koodin saa myös noin 60 kertaa nopeammaksi (120ms) laskemalla tuloksen ensin taulukkoon ja vasta sitten työntämällä grafiikkaobjektiin.
Alla em. tavalla optimoitu frmNoise2_Load
Private Sub frmNoise2_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim i As Integer Dim x, y As Integer Dim bi As New Bitmap(picSurface.Width, picSurface.Height) Randomize() Dim d As Double = Math.Sqrt(200 * 200 + 200 * 200) Dim p(200, 200) As Short For x = 1 To 200 For y = 1 To 200 p(x, y) = 125 Next Next For i = 1 To 500 ' arvotaan suora, joka puolittaa alueen Dim v As Double = Rnd() * 2 * Math.PI Dim a As Double = Math.Sin(v) Dim b As Double = Math.Cos(v) ' c:stä saadaan arvottu numero -d/2 ja d/2 väliltä Dim c As Double = Rnd() * d - d / 2 For x = 1 To 200 For y = 1 To 200 ' tarkistetaan, kummalla puolella viivaa piste on Dim clr = p(x, y) If (a * x + b * y - c > 0) Then ' kirkastetaan clr += 3 If clr > 255 Then clr = 255 Else ' tummennetaan clr -= 3 If clr < 0 Then clr = 0 End If p(x, y) = clr Next Next Next Dim cl(255) As Color For i = 0 To 255 : cl(i) = Color.FromArgb(i, i, i) : Next For x = 1 To 200 For y = 1 To 200 bi.SetPixel(x, y, cl(p(x, y))) Next Next picSurface.BackgroundImage = bi End Sub
Aihe on jo aika vanha, joten et voi enää vastata siihen.