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 ClassKoodista 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 SubAihe on jo aika vanha, joten et voi enää vastata siihen.