FRACTAL DE MANDELBROT

jesusonline Messages postés 6814 Date d'inscription dimanche 15 décembre 2002 Statut Membre Dernière intervention 13 octobre 2010 - 11 févr. 2007 à 01:21
cs_EBArtSoft Messages postés 4525 Date d'inscription dimanche 29 septembre 2002 Statut Modérateur Dernière intervention 22 avril 2019 - 20 mai 2008 à 22:41
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/41440-fractal-de-mandelbrot

cs_EBArtSoft Messages postés 4525 Date d'inscription dimanche 29 septembre 2002 Statut Modérateur Dernière intervention 22 avril 2019 9
20 mai 2008 à 22:41
Et encore... il y a trop de "New" à mon gout !
cs_EBArtSoft Messages postés 4525 Date d'inscription dimanche 29 septembre 2002 Statut Modérateur Dernière intervention 22 avril 2019 9
20 mai 2008 à 22:40
Voila ce que je propose :

Private Structure ARGB
Dim r As Byte
Dim g As Byte
Dim b As Byte
Dim a As Byte
End Structure

Private Declare Ansi Sub Copy Lib "kernel32" Alias "RtlMoveMemory" (ByVal memTo As Integer, ByRef memFrom As ARGB, ByVal Length As Integer)

Public Sub DraMandelbrotFractal()

'Me.Width = ((Me.Width + 3) And Not 3) 'Seulement pour 24Bits RGB

Static _Width As Integer = Me.Width
Static _Height As Integer = Me.Height
Static halfX As Integer = _Width * 2 / 3
Static halfY As Integer = _Height * 0.5
Static siz As Integer = _Width * _Height * 4
Static z1 As Single = 1 / Me._depth * 64
Static z2 As Single = 1 / Me._depth * 255
Static StepX As Integer = 0

Dim Pixels(_Height - 1, _Width - 1) As ARGB
For j As Integer = 0 To (_Height - 1)
For i As Integer = 0 To (_Width - 1)
stepx = Me.GetStep(New Complex((i - halfX) / 150D, (j - halfY) / 150D))
If (stepx > 0) Then
With Pixels(j, i)
.a = 255
.r = z1 * stepx
.b = z2 * stepx
End With
End If
Next
Next

Me._bmpBuffer = New Bitmap(_Width, _Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
Dim bmpData As Imaging.BitmapData = Me._bmpBuffer.LockBits(New Rectangle(0, 0, _Width, _Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
'Marshal.Copy(NewPixel, 0, bmpData.Scan0, NewPixel.Length)
Copy(bmpData.Scan0, Pixels(0, 0), siz)
Me._bmpBuffer.UnlockBits(bmpData)

Graphics.FromImage(Me._bmpBuffer).DrawString("Mandelbrot's Fractal", Me._font, Me._fontBrush, Point.Empty)
Me.CreateGraphics().DrawImage(Me._bmpBuffer, Point.Empty)

End Sub

Apres difficile de faire mieu sans changer le comportement des autres methodes dont celles qui prennent le plus de temps : Complexe et GetStep

Et puis on pourrais creer le bitmap au moment de l'initialisation et pas a chaque fois, bref l'optimisation peut ce faire un peu partout.

@+
guillaume1136 Messages postés 21 Date d'inscription jeudi 10 novembre 2005 Statut Membre Dernière intervention 3 juin 2008
20 mai 2008 à 17:16
comme dans ce coin on parle assembleur (ou on parlait...).
Il me vien une question.

En C++.Net unsafe produit t'il du code IL ou du code natif?

La r?ponse semble a priorie ?tre non, puisse que l'on peut utilis? des objet manag?,
donc il y a utilisation de Handle, donc vraisembleblement on passe par la machine virtuel .Net, donc vraisemblement par le code IL.

Et une deuxi?me question me vien, en C++.Net toujours, les bloc _asm quand ? eux,
en quoi sont il compil? ?

Une traduction de l'assembleur en IL (si c'est possible), ou directement de l'assembleur non manag?.
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
11 févr. 2007 à 19:50
ok Bidou, j'avais bien noté avec ta réponse plus haut au vu de data1->Scan0.
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
11 févr. 2007 à 19:44
Pour le code VB il m'a généré ceci:
Dim numPtr1 As Byte* = DirectCast(data1.Scan0, Byte*)

Ce qui semble étonnant étant donné que d'après toi on ne peut pas utiliser les pointeurs en VB.NET.
Ce qui est sûr c'est que ce qui est généré par Reflector est à prendre avec des pincettes...

Pour revenir à la question de savoir si on n'est obligé de mettre du code natif dans un bloc unsafe en C++.NET, je dirais que non : http://www.springerlink.com/content/h4092285755hu473/
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
11 févr. 2007 à 19:41
"assembleur" a déjà une signification pour le commun dev dont je fais partie:
- mise au format humain des opcodes directement exécutables par le cpu.

Toutes ces usurpations de langage ne devraient pas berner grand monde.

"l'assembleur des langages interprété", voila bien une suite de mots dont chaque suivant contredit le précédent.
jesusonline Messages postés 6814 Date d'inscription dimanche 15 décembre 2002 Statut Membre Dernière intervention 13 octobre 2010 29
11 févr. 2007 à 19:35
Oui mais attention ! Reflector prend le MSIL est ensuite tente de convertir ca dans un autre langage ... Quand on utilise des fonctionnalités un poil tricky Reflector a tendance à générer un peu n'importe quoi, je suis sur qu'il te sort qqchose si tu lui dis de générer du VB.net et je doute que cela compile.

Ce qui faut regarder c'est surtout la partie IL : l'assembleur des langages interprété .net (aussi bien VB.net, C#, C++.net, ...)

(vi j'aime bien faire raler brunews :-))
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
11 févr. 2007 à 19:26
oh la misère, faut avoir tué père et mère pour se taper cette syntaxe.
C'est tellement plus simple à écrire en vrai C avec en plus de bien meilleures perfs et aucun setup, j'espère que le blaireau qui a incité MS à prendre le terme "C++" en dotnetterie aura depuis été affecté à tondre la pelouse.
Merci pour les infos.
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
11 févr. 2007 à 19:13
BruNews> Alors j'ai donné un coup de Reflector sur cette méthode et voici comment il a converti
Mon code C#:
byte* newPixel = (byte*)(void*)bmpData.Scan0;

en C++.NET:
System::Byte __gc** numPtr1 = *static_cast<__box System::Byte __gc***>(data1->Scan0);

Donc apparement ça devrait être faisable en C++.NET aussi dans un bloc unsafe (ceci dit, je n'ai pas testé).
jesusonline Messages postés 6814 Date d'inscription dimanche 15 décembre 2002 Statut Membre Dernière intervention 13 octobre 2010 29
11 févr. 2007 à 17:58
Marshal copy et lock bits sont des méthodes unmanaged (au sens .net) par conséquent mon code est unmanaged :-)

A ma connaissane on ne peut pas utiliser les pointeurs en VB ... :-( donc on peut pas faire la meme chose mais je suis curieux de voir la différence de perf entre C# et VB.net et la méthode MSIL que TKfé a posté sur son blog ...
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
11 févr. 2007 à 17:58
Il y aurait donc bien des sens différents selon le sabir employé.
Pourrais-tu nous indiquer si cette ligne
byte* newPixel = (byte*)(void*)bmpData.Scan0;
passerait dans un bloc unmanaged en C++ .net, me semblait qu'il ne devait y avoir que du natif dans ces blocs.
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
11 févr. 2007 à 17:49
C'est pas de "l'unmanaged", mais de "l'unmanaged .NET" là est certainement la différence...
http://vivekthangaswamy.blogspot.com/2006/11/unsafe-code-in-c.html

Le code de JesusOnline n'est pas directement unmanaged .NET à mon sens car il ne fait pas intervenir de bloc unsafe.
Voici le code que j'ai fait en C# que j'appelerais unmanaged (.NET) :

unsafe
{
byte* newPixel = (byte*)(void*)bmpData.Scan0;
for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; x += 3)
{
Color color = XXX;
newPixel[0] = color.B;
newPixel[1] = color.G;
newPixel[2] = color.R;
newPixel += 3;
}
newPixel += offset;
}
}
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
11 févr. 2007 à 17:23
unsafe ok
'unmanaged' n'indiquerait pas un bloc de code en NATIF ? C'est le cas en C++ .NET, bizzare si les mots n'ont plus le même sens d'un sabir l'autre.
S'il a le même sens, me semble impossible d'avoir 'unmanaged' en VB comme en C#, je ne vois d'ailleurs que de l'interprété dans le code.
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
11 févr. 2007 à 09:46
Cyril> Oui, en fait je pensais à un bloc unsafe (que j'ai écrit et qui marche) mais les couleurs ne joue plus tout à fait. J'ai pas encore regardé en détail pourquoi... mais je vais certainement trouvé la réponse dans ce très bon article dont tu as donné le lien.

Badr> Aucun risque, après utilisation et comparaison des deux, je me sens nettement plus à l'aise avec C# (et il n'a jamais été question d'arrêter C#) :-p
cs_badrbadr Messages postés 475 Date d'inscription jeudi 19 juin 2003 Statut Membre Dernière intervention 3 novembre 2008 1
11 févr. 2007 à 03:11
Dit moi Bidou, depuis quand tu code en vb.net?
On va te voir quand même sur csharpfr hein, rassure moi :)
jesusonline Messages postés 6814 Date d'inscription dimanche 15 décembre 2002 Statut Membre Dernière intervention 13 octobre 2010 29
11 févr. 2007 à 01:21
Voici une version non managé :

''' ------------------------------------------------------------------------
''' <summary>
''' Draw the fractal.
''' </summary>
''' <remarks> For more performance, use unmanaged code [unsafe]. </remarks>
''' ------------------------------------------------------------------------
Public Sub DraMandelbrotFractal()
Dim gfx As Graphics = Me.CreateGraphics()
Me._bmpBuffer = New Bitmap(Me.Width, Me.Height, gfx)

Dim halfX As Integer = 2 * Me._bmpBuffer.Width / 3
Dim halfY As Integer = Me._bmpBuffer.Height / 2
Dim i As Integer, j As Integer = 0

Dim bmpData As Imaging.BitmapData = Me._bmpBuffer.LockBits(New Rectangle(0, 0, width, Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
Dim newPixel(width * height - 1) As Integer
Marshal.Copy(bmpData.Scan0, newPixel, 0, newPixel.Length)
For j = 0 To Me.Height - 1
For i = 0 To Me.Width - 1
Dim complex As Complex = New Complex((i - halfX) / 150D, (j - halfY) / 150D)

Dim temp As Integer = newPixel(Me.Width * j + i)
newPixel(Me.Width * j + i) = Me.GetColor(Me.GetStep(complex)).ToArgb()

Next
Next

Marshal.Copy(newPixel, 0, bmpData.Scan0, newPixel.Length)
Me._bmpBuffer.UnlockBits(bmpData)
Graphics.FromImage(Me._bmpBuffer).DrawString("Mandelbrot's Fractal", Me._font, Me._fontBrush, Point.Empty)
gfx.DrawImage(Me._bmpBuffer, Point.Empty)
End Sub


Pour en savoir plus il faut lire http://www.techheadbrothers.com/Articles.aspx?Id=8d3eb481-8a98-42a6-8033-e851c797aa60&p=3
Rejoignez-nous