Weicher Farbverlauf schwarz->regenbogenfarben->weiss
Übersicht

HawkinsBetreff: Weicher Farbverlauf schwarz->regenbogenfarben->weiss |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hoi,
weil ich für ein Fraktalprogramm möglichst alle Farben ausnutzen wollte aber weiche verläufe, hab ich diese Funktion geschrieben. Will man einzelne Pixel zeichnen, muss die Farbe als Integezahl angegeben werden. Zählt man einfach von 0 hoch bis zum maximum (256*256*256 - 1), dann ergibt sich kein Farbverlauf, sondern viele bunte Streifen. Die Funktion benötigt eine Zahl zwischen 0 und 1, sie liefert den Farbwert zurück, der dem Farbverlauf entspricht. (siehe beispiel) es fadet in folgender reihenfolge die farben durch schwarz -> rot -> gelb -> grün -> türkis/cyan -> blau -> lila/magenta -> weiss Es ist deshalb zwischen 0 und 1, sodass mman ohne viel umzurechnen, einfach direkt runterteilen kann. Code: [AUSKLAPPEN] Graphics 400,300,16,2
SetBuffer FrontBuffer() Repeat Cls For i = 0 To GraphicsWidth()-1 For j=GraphicsHeight()/2 -5 To GraphicsHeight()/2 + 5 WritePixel i,j,rgbfade(Float(i)/GraphicsWidth()) Next Next Until KeyHit(1) Function rgbfade(value#);0-1 value#=value#*7 rise#=(value# Mod 1):fall#=1-rise# If Floor(value#)=0 Then r%=rise#*255:g%=0:b%=0 If Floor(value#)=1 Then r%=255:g%=rise#*255:b%=0 If Floor(value#)=2 Then r%=fall#*255:g%=255:b%=0 If Floor(value#)=3 Then r%=0:g%=255:b%=rise#*255 If Floor(value#)=4 Then r%=0:g%=fall#*255:b%=255 If Floor(value#)=5 Then r%=rise#*255:g%=0:b%=255 If Floor(value#)=6 Then r%=255:g%=rise#*255:b%=255 colorcode=r%*256^2+g%*256+b% Return colorcode% End Function Hier ist die Funktion zusammen mit dem Beispiel. Man sieht, das in der Funktion 7 Sektoren sind (0 bis 6) bei der immer eine Farbe fest ist (0 oder 255) und eine andere gerade gefadet wird mit rise# oder fall# SOmit kann die Funktion auch umgebaut werden um andere Farbverläufe zu erzeugen. Hier eine Skizze, die verdeutlicht, welche Farben wann hochgefaet werden. Die Zahlen oben geben die Sektoren an, links steht, welcher Farbkanal gefadet wird Alles für das "normale" Blitz 2d, damit es möglichst überall läuft (ausser blitzmax). (Würde nicht automatisch immer dieser Beitrag beim schrieben nach oben scrollen, sodass man blind schrieben muss, würde ich auch tippfehler, groß/kleinschreibung korrigieren. liegt bestimmt am iexplorer :-( ) |
||
![]() |
TimBo |
![]() Antworten mit Zitat ![]() |
---|---|---|
nice, sieht nicht schlecht aus, obwohl es doch geschickter wäre das Bild einmal vor der Hauptschleife per CreateImage zu zaubern und dann nur DrawImage auszuführen.
Dürfte das Tempo extrem Steigern. Grüße TimBo |
||
mfg Tim Borowski // CPU: Ryzen 2700x GPU: Nvidia RTX 2070 OC (Gigabyte) Ram: 16GB DDR4 @ 3000MHz OS: Windows 10
Stolzer Gewinner des BCC 25 & BCC 31 hat einen ersten Preis in der 1. Runde beim BWInf 2010/2011 & 2011/12 mit BlitzBasic erreicht. |
![]() |
hazumu-kun |
![]() Antworten mit Zitat ![]() |
---|---|---|
Genau, lass den Frabverlauf vorberechnen, nach bestimmten Parametern, und dann wenn man die Farben durchfaden will wird mit Readpixel gearbeitet.
Die Idee von Schwarz-Rot-...-Blau-lila undso ist gut, entspricht sogar bis auf das Ende dem Lichtspektrum. (Weiß als elementarfrabe gibt es als lichtwelle nicht, magenta prinzipiell auch nicht.) Ich würde noch eine option einbauen das nur lichtfarben angezeigt werden, das ist für einen echten Regenbogen sinnvoller. |
||
Warum kann es keine omnipotente Macht geben?
Weil diese omnipotente Macht in der Lage sein müsste, einen so schweren Stein zu schaffen, dass sie ihn nicht heben kann -> nicht omnipotent |
Hawkins |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Danke für Euer feedback. Genau sowas hilft mir das zu verbessern. Ich bin immer sehr unzufrieden mit meinen Programmen weil ich immer weiss, man könnte da bestimmt was verbessern.
Die richtigen Kniffe und Tricks beherrsche ich noch nicht. @ TimBo Zitat: obwohl es doch geschickter wäre das Bild einmal vor der Hauptschleife per CreateImage zu zaubern und dann nur DrawImage auszuführen.
Dürfte das Tempo extrem Steigern. Naja, das ganze einfach als Bild abzuspeichern und dann zu zeichnen würde nur dann was bringen, wenn man direkt so einen farbigen Balken haben möchte. Aber das war ja nur ein Beispiel. In den Anwendungen soll die Funktion ja dazu dienen einfach einen Parameter per Farbe anzuzeigen. Sagen wir mal, wir haben eine 3D Funktion z=ƒ(x,y) aber wir wollten keine 3D Graphik anzeigen, sondern die 2D-Ebene, dafür aber die z-Werte je nach Wert in einer anderen Farbe. Hätte ich nur einen übergang von schwarz zu rot, dann gäbe es nur 256 Verschiedene Farben, und somit Werte, die für z Unterschieden werden könnten. Und mit dem Auge wäre es unmöglich aus dem Farbton ein zu schätzen, welchen wert z hätte. Dadurch, dass ich ein möglichst großes Frabspektrum einsetze, wo jede Farbe nur einmal vorkommt (deshalb wird am Ende ins weisse gefadet), lässt sich z besser ablesen und es sieht halt eben auch recht schön aus, wie ich finde. Aber ich glaube, mit dem vorher abspeichern das lässt sich trotzdem noch nutzen, wie auch viken_emesh erklärt hatte. @ viken_emesh Also du meinst, man sollte den Farbverlauf vorzeichnen, ein Pixel hoch und dafür die volle Auflösung breit (in diesem Fall 7*256 = 1792), das ganze aber in einen anderen Buffer zeichnen und dann mit ReadPixel lesen? Hmm, da verstehe ich noch nicht, wie das gehen könnte. Achso, ich poste mal die Anwendung, für den ich den Farbverlauf benötigt habe, dann wird klarer wozu er dienen könnte, wie flexibel er seinmüsste, was möglich ist und was nicht. Ich weiss nur noch nicht, wo ich das posten soll, denn hier unter Codearchiv steht unter "Wie poste ich richtig" dass keine kompletten Spiele/Module hochgeladen werden sollen. Aber ein richtiges Projekt was unter "sonstiges -> Projekte" gehört, ist es ja auch nicht... naja, hier der Link https://www.blitzforum.de/foru...p?p=341562 |
||
Krischan |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hast Du Dir schon einmal meine Farbverlaufsfunktion angeschaut? Die ist recht einfach einzusetzen, flexibel und arbeitet mit Arrays.
https://www.blitzforum.de/foru...hp?t=29955 |
||
Krischan |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ich habs mal eingebaut und es funzt. Zwei Anmerkungen: Deine Funktion liefert nicht 0...1 sondern 0.x-1 zurück, mit 255 multipliziert ergibt das 25 bis 255, ich habe mal eine schnelle Normalisierung eingebaut, so dass die Rottöne auch bei rot anfangen. Richtig gut geschrieben wäre es, wenn man alle Werte einmal ausrechnet und zwischenspeichert, dabei den min/max Wert zeitgleich herausfindet und in einer weiteren Funktion dann den normalisierten Wert als Bild ausgibt. Den Ansatz dafür habe ich mal eingebaut.
Und dann ist dein Programm auch noch viel schneller geworden wenn man Flip 0 verwendet: Code: [AUSKLAPPEN] Graphics 800,600,32,2
SetBuffer BackBuffer() Global c#,ci#,maxit%,ra# Global zoom#,xoff#,yoff# Global maxx%,maxy%,bit1%=1 Dim Prozent#(0),Rot%(0),Gruen%(0),Blau%(0) Const maxcols%=256 Global SpectrumR%[maxcols],SpectrumG%[maxcols],SpectrumB%[maxcols] Global min=65536,max=0 Restore Spektrum CreateGradient(11,maxcols,False,SpectrumR,SpectrumG,SpectrumB) initvalues() Repeat For i=0 To maxx-1 ;If Not bit1% Then AppTitle "Julia-Fraktal c = "+c#+" + "+ci#+"i Iterationen = "+maxit% ;If bit1% Then AppTitle "Mandelbrot-Fraktal" + " Iterationen = " + maxit% control() LockBuffer BackBuffer() For j=0 To maxy-1 x#=Float(xoff#+i-maxx/2)/(maxy/2) y#=Float(yoff#+j-maxy/2)/(maxy/2) x#=x#/zoom#:y#=y#/zoom# If Not bit1% Then col%=Int(Floor(jtransform(x#,y#,maxit%)*255)) If bit1% Then col%=Int(Floor(mtransform(x#,y#,maxit%)*255)) If col<min Then min=col If col>max Then max=col col=Norm(col,25,255,0,255) rgb=SpectrumR[col]*$10000+SpectrumG[col]*$100+SpectrumB[col] WritePixelFast i,j,rgb Next UnlockBuffer BackBuffer() AppTitle min+","+max Flip 0 Next Until KeyHit(1) End Function initvalues() ;c#=0 : ci#=0 c#=-0.74 : ci#=0.12 ;MS ;c#=-0.6 : ci#=0.6 ;Cantor-Staub ;c#=0.11031 : ci#=0.67037 ;Fatou-Staub ;c#=-0.39054 : ci#=0.58679 ;Siegel-Disk maxx%=GraphicsWidth():maxy%=GraphicsHeight() xoff#=0:yoff#=0:zoom# = 0.6 maxit%=50 : ra# = 2000000 End Function Function jtransform#(x#,y#,maxit%) it%=0 Repeat x1#=x#^2 - y#^2 + c# y1#=2*x#*y# + ci# distance#=Sqr(x1#^2+y2#^2) x#=x1#:y#=y1#:it%=it%+1 Until it%>=maxit% Or distance#>=ra# Return Float(it%)/Float(maxit%) End Function Function mtransform#(c#,ci#,maxit%) it%=0 Repeat x1#=x#^2 - y#^2 + c# y1#=2*x#*y# + ci# distance#=Sqr(x1#^2+y2#^2) x#=x1#:y#=y1#:it%=it%+1 Until it%>=maxit% Or distance#>=ra# Return Float(it%)/Float(maxit%) End Function Function control() If KeyHit(57) Then bit1%=1-bit1% zoom#=zoom#/(2^KeyHit(74)):xoff#=xoff/(2^KeyHit(74)):yoff#=yoff/(2^KeyHit(74)) zoom#=zoom#*(2^KeyHit(78)):xoff#=xoff*(2^KeyHit(78)):yoff#=yoff*(2^KeyHit(78)) If KeyHit(203) Then xoff#=xoff#-maxx/4 If KeyHit(205) Then xoff#=xoff#+maxx/4 If KeyHit(200) Then yoff#=yoff#-maxy/4 If KeyHit(208) Then yoff#=yoff#+maxy/4 maxit%=maxit%+10*KeyHit(201) maxit%=maxit%-10*KeyHit(209) ci#=ci#-0.02*KeyHit(31) ci#=ci#+0.02*KeyHit(17) c#=c#-0.02*KeyHit(30) c#=c#+0.02*KeyHit(32) If KeyHit(14) Then initvalues() If KeyHit(1) Then End End Function Function rgbfade(value#);0-1 value#=value# Mod 1 value#=value#*7 rise#=(value# Mod 1):fall#=1-rise# If Floor(value#)=0 Then r%=rise#*255:g%=0:b%=0 If Floor(value#)=1 Then r%=255:g%=rise#*255:b%=0 If Floor(value#)=2 Then r%=fall#*255:g%=255:b%=0 If Floor(value#)=3 Then r%=0:g%=255:b%=rise#*255 If Floor(value#)=4 Then r%=0:g%=fall#*255:b%=255 If Floor(value#)=5 Then r%=rise#*255:g%=0:b%=255 If Floor(value#)=6 Then r%=255:g%=rise#*255:b%=255 colorcode=r%*256^2+g%*256+b% Return colorcode% End Function Function CreateGradient(colors%,steps%,inverse=False,R%[maxcols],G%[maxcols],B%[maxcols]) Dim Prozent#(colors),Rot%(colors),Gruen%(colors),Blau%(colors) Local i%,pos1%,pos2%,pdiff% Local rdiff%,gdiff%,bdiff% Local rstep#,gstep#,bstep# Local counter%=0 ; Farbcodes einlesen und ggf. invertieren If inverse Then For i=colors To 1 Step -1 Read Prozent(i),Rot(i),Gruen(i),Blau(i) Prozent(i)=100.0-Prozent(i) Next Else For i=0 To colors-1 : Read Prozent(i),Rot(i),Gruen(i),Blau(i) : Next EndIf ; Gradient berechnen While counter<colors ; Prozent in Step-Position umrechnen pos1=Prozent(counter)*steps*1.0/100 pos2=Prozent(counter+1)*steps*1.0/100 ; Abstand berechnen pdiff=pos2-pos1 ; Differenz zwischen den Farben berechnen rdiff%=Rot(counter)-Rot(counter+1) gdiff%=Gruen(counter)-Gruen(counter+1) bdiff%=Blau(counter)-Blau(counter+1) ; Schrittweite zwischen den Farben berechnen rstep#=rdiff*1.0/pdiff gstep#=gdiff*1.0/pdiff bstep#=bdiff*1.0/pdiff ; Zwischenfarbcodes berechnen For i=0 To pdiff R[pos1+i]=Int(Rot(counter)-(rstep*i)) G[pos1+i]=Int(Gruen(counter)-(gstep*i)) B[pos1+i]=Int(Blau(counter)-(bstep*i)) Next ; Zähler erhöhen counter=counter+1 Wend End Function ; normalize a value Function Norm#(v#=128.0,vmin#=0.0,vmax#=255.0,nmin#=0.0,nmax#=1.0) Return ((v-vmin)/(vmax-vmin))*(nmax-nmin)+nmin End Function .Spektrum Data 0.0,255, 0, 0 ; rot Data 10.0,255,128, 0 ; orange Data 20.0,255,255, 0 ; gelb Data 30.0,128,255, 0 ; gelbgrün Data 40.0, 0,255, 0 ; grün Data 50.0, 0,255,128 ; grüntürkis Data 60.0, 0,255,255 ; türkis Data 70.0, 0,128,255 ; hellblau Data 80.0, 0, 0,255 ; blau Data 90.0,128, 0,255 ; violett-blau Data 100.0, 0, 0, 0 ; scharz |
||
![]() |
DAK |
![]() Antworten mit Zitat ![]() |
---|---|---|
danke!
habs auf bmax umgeschrieben und da sehr gut verwenden können. genau was ich gebraucht hab! |
||
Gewinner der 6. und der 68. BlitzCodeCompo |
Hawkins |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
joa hab mir das mal angeschaut @ krischan.
wär nur nicht der sourcecode so lang und arrays versuche ich auch zu umgehen. Ich will imemr ganz kleine funktionen, die auch garnicht großartig auffallen udn möglichst wenig speicher verwenden. ein ansatz von mir um einen regenverlauf zu machen war auch, die drei kanäle rot grün blau mit nem sinus zu steuern, der je nach kanal 120° verschoben ist (wie beim drehstrom) somit hat man imemr die gleiche helligkeit. leider ist die sättigung dann nicht immer 100%, weil ja auch dann von jeder farbe ein kleienr anteil drin ist. es wirkt also manchmal "gräulich" ah freut mich, dass es schon der erste verwenden konnte ^^ |
||
Krischan |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Verstehe ich nicht, die Funktion ist eher kurz und viel Speicher verbraucht sie auch nicht. | ||
Hawkins |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Naja man hat mehrere Funktionen. Aber ich hab mir überlegt, dass wenn man es vorspeichert, man ja auch wiederum 2 Funktionen benötigt.
Naja... Achso, dass es im Beispiel langsam ist, liegt aber garnicht an dem RGB-Verlauf, sondern einfach am Writepixel mit dem flip. Und dass es flip 0 auch gibt, ist mir garnicht aufgefallen. das ändert ja alles.. auch mein fraktalprogramm... das muss ich gleich mal testen. Danek schön |
||
Hawkins |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
nein, es hat mir einfach keine ruhe gelassen:
Ich hab mir noch ne Möglichkeit ausgedacht, wie man den Farbverlauf machen könnte: Man muss eine Funktion für jeden Farbkanal entwickeln... ich weiss nicht wie ich es erklären kann, aber hier mal ne Zeichnung: Man sieht oben ist das Verhalten, wie der rote Kanal sich verhalten soll. Untendrunter die Funktion, die das Verhalten beschreibt, ohne die Werte oberhalb von 1 und unterhalb von 0 ab zu schneiden. Bei meinem speziellen Farbverlauf wäre das also für rot wie im Bild zu sehen: r(x) = abs(-abs(-x+1.5)+2.5)-1 der grüne kanal ist gerade punktsymmetrisch dazu (muss aber nen offset bekommen, dass es stimmt), also g(x) = -r(7-x)+1 = abs(abs(7-x-1.5)-2.5)+2 = abs(abs(5.5-x)-2,5)+2 und blau ist zum glück trivialerweise b(x)=x-3 also r(x) = abs(-abs(-x+1.5)+2.5)-1 g(x) = -abs(abs(5.5-x)-2,5)+2 b(x) = x-3 (der verlauf zwischen 0 und 7, lässt sich aber wieder normieren) die funktionen müssen nur noch geshickt "beschnitten" werden, sodass sie nicht größer als 1 udn nicht kleiner als 0 werden. Aber ich weiss nicht, ob mit diesem Ansatz die Funktion noch schneller ist, aber vom Source her müsste dieser Ansatz um einiges eleganter sein. Wie kann ich auf die effektiste und kürzeste weise die funktionen begrenzen, dass die zwischen 0 und 1 bleiben? und kennt noch jemand einen noch eleganteren Ansatz? Nachtrag: Ich glaube das abschneiden der Werte unter null und über 1 könnte man so machen: r = (r>0)*(r<1)*r + (r>=1) nach-nachtrag: Also so funktioniert es auch: Code: [AUSKLAPPEN] Function rgbfade(value#);0-1
value#=value#*7 r#=Abs(-Abs(-value#+1.5)+2.5)-1: g#=-Abs(Abs(5.5-value#)-2.5)+2 b#=value#-3 r# = (r#>0)*(r#<1)*r# + (r#>=1) g# = (g#>0)*(g#<1)*g# + (g#>=1) b# = (b#>0)*(b#<1)*b# + (b#>=1) Return Int(r#*255)*256^2+Int(g#*255)*256+Int(b#*255) End Function Aber nun hab ich wieder für r,g und b float werte, aber damit könnte man ja leben. Aber es muss noch ne bessere udn Kürzere Lösung geben.... |
||
Hawkins |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hier die Funktion in einem weiteren Beispielprogramm für einen weichen verlauf durch das Regenbogenspektrum.
Es lässt sich daraus ein geschlossener Farbkreis bilden. Code: [AUSKLAPPEN] maxx=800:maxy=600
Graphics maxx,maxy,16,2 SetBuffer BackBuffer() Repeat For px = 0 To maxx-1 LockBuffer BackBuffer() For py = 0 To maxy-1 x#=2*(px-maxx/2.0)/maxy : y#=2*(py-maxy/2.0)/maxy gradientpos#=180+ATan2(y,x)/360 If (x#^2 + y#^2 < 1) And (x#^2 + y#^2 > 0.8) Then WritePixelFast px,py,rainbow(gradientpos#) Next UnlockBuffer BackBuffer() If KeyHit(1) Then End Flip 0 Next Until KeyHit(1) Function rainbow(value#);0-1 value#=value#*6 Mod 6 r#=Abs(3-value#)-1 :r# = (r#>0)*(r#<1)*r# + (r#>=1) g#=-Abs(2-value#)+2 :g# = (g#>0)*(g#<1)*g# + (g#>=1) b#=-Abs(4-value#)+2 :b# = (b#>0)*(b#<1)*b# + (b#>=1) Return Int(r#*255)*256^2+Int(g#*255)*256+Int(b#*255) End Function |
||
- Zuletzt bearbeitet von Hawkins am So, Aug 16, 2009 21:22, insgesamt 2-mal bearbeitet
![]() |
Nicdel |
![]() Antworten mit Zitat ![]() |
---|---|---|
Nimm BITTE nicht BMP sondern PNG! Es ist kleiner und verlustfrei. Nicht jeder hat eine 16000-Leitung. | ||
Desktop: Intel Pentium 4 2650 Mhz, 2 GB RAM, ATI Radeon HD 3850 512 MB, Windows XP
Notebook: Intel Core i7 720 QM 1.6 Ghz, 4 GB DDR3 RAM, nVidia 230M GT, Windows 7 |
Hawkins |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Nicdel hat Folgendes geschrieben: Nimm BITTE nicht BMP sondern PNG! Es ist kleiner und verlustfrei. Nicht jeder hat eine 16000-Leitung.
Vielen Dank für den Tipp. Habs auch direkt geändert. Ich wusste nie, für was das png-Format da ist. Aber das scheint ja wirklich verlustfrei zu sein. Das werd ich mir merken und öfters benutzen |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group