Huomasin kauan sitten Fawkzin koodanneen metapallot assemblerille.
En koodista mitään ymmärtänyt, mutta päätin siinä samassa koodaavani saman joskus VB:lle(Kunhan oppisin ymmärtämään hieman enemmän matikkaa)
Nyt ymmärrän ja sain projektini valmiiksi!
Googletin hetken ja löysin kaavan, jolla sähkökentän vaikutus lasketaan(y=1/x^2).
Tuosta kaavasta muuten voi muodostaa kappaleen, jonka tilavuus on äärellinen, mutta pinta-ala ääretön(kiepauta kuvaaja x-akselin ympäri)
(mistäköhän tuon olen lukenut, en edes muista)
No pidemmittä löpinöittä koodin kimppuun.
En taaskaan viitsinyt sitä "Windows Form Designer generated code" -regionia poistaa, se ei ollut hirveän pitkä.
Olen selittänyt kaikki kaavasta johtamani jutut koodissa.
Täsmennetään vielä hiukan tuota ' säde / ((sijaintix - ruutux)^2 + (sijaintiy - ruutuy)^2) kohtaa:
sijaintix:stä ja sijaintiy:stä siis vähennetään ruutux ja ruutuy, jotta saadaan "pallon" koordinaatit(kuvaaja) transformoitua maailmakoordinaateiksi(selvensiköhän tuo).
en kaavaani osaa oikein paremmin selittää.
Jos joku tämän saa toimimaan, niin kuulisin mielelläni kritiikkiä.
Lisää infoa voi lukea putkan metapallot oppaasta.
P.S. Pallot ovat sinisiä, koska olen hulluna siniseen. Se on lempivärini. Ah... ...Sininen ;)
P.S.2 Kannattaa kokeilla eri THRESOLD -arvoja...
P.S.3 Kannattaa kokeilla myös eri VARI -arvoja...
Public Class frmBalls
Inherits System.Windows.Forms.Form
Const THRESOLD As Double = 0.2 ' Pistä tähän arvo väliltä 0 - 1
Const VARI As Byte = 0 ' 0 = sininen; 1 = vihreä; 2 = punainen; 3 = valkoinen
Structure MetaBall
Dim pos As PointF
Dim rad As Integer
Dim mass As Integer
Dim vel As PointF
End Structure
Dim Balls(2) As MetaBall
Dim bf(300, 300) As Double
Dim b As Bitmap
Dim g As Graphics
Dim Phi As Double
Dim STab(360) As Double
Dim CTab(360) As Double
#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(304, 304)
Me.picSurface.TabIndex = 0
Me.picSurface.TabStop = False
'
'frmBalls
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(304, 302)
Me.Controls.Add(Me.picSurface)
Me.Name = "frmBalls"
Me.Text = "Metaballs"
Me.ResumeLayout(False)
End Sub
#End Region
Private Sub frmBalls_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim x, y, i As Integer
Randomize()
' kosini ja sini taulukot etukäteen...
For i = 0 To 360
' i / 360 = rad / 2pi |kerrotaan ristiin
' i*2pi = 360rad |:360
' i*2pi/360 = rad
STab(i) = Math.Sin(i * 2 * Math.PI / 360)
CTab(i) = Math.Cos(i * 2 * Math.PI / 360)
Next
' alustetaan pallot
For i = 0 To Balls.Length - 1
Balls(i).rad = Int(Rnd() * 100) + 100
Balls(i).mass = Int(Rnd() * 20) + 10
Next
b = New Bitmap(picSurface.Width, picSurface.Height)
g = Graphics.FromImage(b)
picSurface.BackgroundImage = b
End Sub
Private Sub frmBalls_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Activated
Dim x, y, i, j As Integer
Dim v As PointF
Do
Phi += 5
If Phi > 360 Then Phi = 0
' liikutellaan palloja
Balls(0).pos.X = STab(Phi) * 90 + 150 + CTab(Phi) * 70
Balls(0).pos.Y = CTab(Phi) * 10 + 150 + STab(Phi) * 70
Balls(1).pos.X = CTab(Phi) * 30 + 150 + CTab(Phi) * 70
Balls(1).pos.Y = CTab(Phi) * 60 + 150 + STab(Phi) * 70
Balls(2).pos.X = CTab(Phi) * 50 + 150 + CTab(Phi) * 70
Balls(2).pos.Y = STab(Phi) * 50 + 150 + STab(Phi) * 70
' tyhjennetään, jos tätä ei tehtäisi kaikki jäisi näyttöön
' kaikki THRESOLDia himmeämmät värit jäisivät näyttöön
g.Clear(Color.Black)
For i = 0 To Balls.Length - 1
' hidashan tämä on, mutta mielestäni VB koodiksi TOSI nopea
' Lasketaan vain pallon ympäriltä
Dim xi, xa, yi, ya As Integer
xi = Balls(i).pos.X - Balls(i).rad * 1.5
If xi < 0 Then xi = 0
xa = Balls(i).pos.X + Balls(i).rad * 1.5
If xa > 300 Then xa = 300
yi = Balls(i).pos.Y - Balls(i).rad * 1.5
If yi < 0 Then yi = 0
ya = Balls(i).pos.Y + Balls(i).rad * 1.5
If ya > 300 Then ya = 300
For x = xi To xa
For y = yi To ya
' Saadaan kaavasta y = 1 / x^2 (sähkökentän vaikutusalue).
' Nippelitietoa tämä on, mutta tästä kaavasta saadaan
' muodostettua kappale, jonka tilavuus on äärellinen,
' mutta pinta-ala ääretön(kiepauta tämän funktion kuvaaja x-akselin ympäri)
' kaava muutetaan muotoon:
' säde / ((sijaintix - ruutux)^2 + (sijaintiy - ruutuy)^2)
bf(x, y) += Balls(i).rad / ((Balls(i).pos.X - x) * (Balls(i).pos.X - x) + _
(Balls(i).pos.Y - y) * (Balls(i).pos.Y - y))
If i = Balls.Length - 1 Then
' Viimeinen pallo -> bf ei enää muutu
' jotta ei ylittäisi yhtä -> ei virhettä väristä
If bf(x, y) > 1 Then bf(x, y) = 1
' Rajoitetaan tummin väri
' Piirretään vain jos kirkkaus on suurempi kuin THRESOLD.
' Tämä on loistava optimointi(Keksin sattumalta), sillä Graphics:in Clear metodi
' on PALJON nopeampi kuin jokaisen pikselin asettaminen yksitellen.
If bf(x, y) > THRESOLD Then
Dim a As Integer = bf(x, y) * 255
Select Case VARI
Case 0
b.SetPixel(x, y, Color.FromArgb(0, 0, a))
Case 1
b.SetPixel(x, y, Color.FromArgb(0, a, 0))
Case 2
b.SetPixel(x, y, Color.FromArgb(a, 0, 0))
Case 3
b.SetPixel(x, y, Color.FromArgb(a, a, a))
End Select
End If
'nollataan, koska arvoa ei enää tarvita
bf(x, y) = 0
End If
Next
Next
Next
picSurface.BackgroundImage = b
picSurface.Refresh()
Application.DoEvents()
Loop
End Sub
Private Sub frmBalls_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed
' Jotta ei kävisi niin kuin aiemmassa Raytracing ohjelmassani ;)
End
End Sub
End ClassSaiskos binäärii?
Mulla ei toiminu, vaikka mulla on vb.net. Näin se valitti: "Invalid parameter used".
Minulla ei valita. Tosin käytän vb.Net 2003:sta
Minulla alkaa aina valittaa noista Publiceista, pitäiskö ne pistää johonkin moduuliin vai pitääkö olla VB6?
Ota ne publicit pois. Pitää olla VB.NET 2003, saattaa toimia myös 2002:lla
peki kirjoitti:
Tuosta kaavasta muuten voi muodostaa kappaleen, jonka tilavuus on äärellinen, mutta pinta-ala ääretön(kiepauta kuvaaja x-akselin ympäri)
(mistäköhän tuon olen lukenut, en edes muista)
Uusimmasta Tieteen kuvalehdestä.
Siinähän se oli. Täytyypä kaivaa esiin ja lukea uudestaan. ;)
Käyrä y=1/x pyörähtää x-akselin ympäri alkaen pisteestä x=1. Siitä syntyvän pyörähdyskappaleen tilavuus on pii, mutta pinta-ala ääretön. Ps. Kivat pallot :).
Okei. Okei. Kiitos täsmennyksestä, mu´tta mitäs tuumaat itse palloista?
Hemmetin .NET, ei ois missään binarya ku mulla ei ole kääntäjä/tulkkia? :/
Koodista on nyt poistettu "siniset palkit" bugi
Ihan hieano, voisin koittaa vääntää tota joskus vb:lle mutten nyt kerkii, binärit on http://koti.mbnet.fi/koodaaja/jotaki/Metaballs.
Värkkäsin metapallot Delphille (tuon uuden oppaan pohjalta).
Eli jos tuo ylempi exe ei jostain syystä toimi, niin tämä:
http://www.members.lycos.co.uk/ezuli/seka/Meta.
toimii lähes takuu varmasti. Kuva piirtyy kun klikkaat
hiirellä. Jos klikkaat toisen kerran, niin kuva "zoomautuu".
Olisi kyllä pitänyt lukea tuo koodi ennen edellistä.
Siis tuo minun on tehty oppaan pohjalta, joten siinä
pallot ei liiku, vaan jokaisella käynnistys kerralla
piirtyy eri paikkaan. Eikä kuva zoomaudu, vaan pallot
suurenee.
Sooda: mitähän tuo sinun ohjelmasi yrittä tehdä sulkeutessa kun suoritan sitä internet tilassa ja suljettaessa tulee SecurityExpection.
meitzi: se on wanha versio kai sitten, peki meilas sen kai mulle ennen ku teki tohon jotain muutoksia :P
Harmi, kun ei ole VB.NETiä, niin en voi kokeilla tuota, mutta idean kyllä tajusin, kiitos pekin oppaan, ja osaan nyt tehdä omia metapallodemoja QBasicilla ja Visual Basicilla. Lukekaa kaikki kiinnostuneet tuo opas. Saattaa vaikuttaa monimutkaiselta, mutta on itse asiassa todella yksinkertaista, ja todella hieno efekti. :)
Tuli vaan tommosta:
'Sub Main' was not found in 'WindowsApplication2.Form1'.
Aihe on jo aika vanha, joten et voi enää vastata siihen.