1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen
  2. Bitte schaltet eure Ad Blocker aus. SLinfo kann nur betrieben werden, wenn es durch Werbung Einnahmen erzielt. Vielen Dank!!
    Information ausblenden
  3. Wir freuen uns, wenn du dich in unserem Forum anmeldest. Bitte beachte, dass die Freigabe per Hand durchgeführt wird (Schutz vor Spammer). Damit kann die Freigabe bis zu 24 Stunden dauern.
    Information ausblenden

llGetColor() to HEX

Dieses Thema im Forum "Fragen zu Scripting" wurde erstellt von Archon Short, 17. März 2016.

  1. Archon Short

    Archon Short Administrator Mitarbeiter

    Beiträge:
    5.147
    Zustimmungen:
    730
    Punkte für Erfolge:
    124
    Nach anfänglichen Problemen hier nun das Script um aus dem Vector der Farbe einen HEX Wert zu machen:
    Code:
    integer     iComponentLength    = 2;
    string      sHexPrefix          = "0x";
    float       fColorMax           = 255.0;
    vector vColorFromHex(string sColor)
    {
            string sX; string sY; string sZ; integer iHelper; vector vColor;
            iHelper = 0;
            sX = llGetSubString(sColor, iHelper, iHelper + iComponentLength - 1);
            iHelper = iHelper + iComponentLength;
            sY = llGetSubString(sColor, iHelper, iHelper + iComponentLength - 1);
            iHelper = iHelper + iComponentLength;
            sZ = llGetSubString(sColor, iHelper, iHelper + iComponentLength - 1);
           
            vColor = <((integer)(sHexPrefix + sX)) / fColorMax, ((integer)(sHexPrefix + sY)) / fColorMax, ((integer)(sHexPrefix + sZ)) / fColorMax>;
            return vColor;
    }
    string to_hex(integer ii)
    {
        if (ii==0) return "00";
        integer i1 = (integer)ii/16;
        integer i2 = (integer)(ii-(i1*16));
        string hexnumbers="0123456789abcdef";
        return llGetSubString(hexnumbers, i1, i1) + llGetSubString(hexnumbers, i2, i2);
    }
    
    default
    {
        state_entry()
        {
            llOwnerSay((string)vColorFromHex("6599db"));
        }
        touch_start(integer honk)
        {
            vector col = llGetColor(2);
            integer R = llFloor(col.x*256);
            integer G = llFloor(col.y*256);
            integer B = llFloor(col.z*256);
            if(R == 256) R= 255;
            if(G == 256) G= 255;
            if(B == 256) B= 255;
            string SR = to_hex(R);
            string SG = to_hex(G);
            string SB = to_hex(B);
           
            llOwnerSay((string)col);
            llOwnerSay("HEX = "+SR+SG+SB);
            llOwnerSay((string)vColorFromHex(SR+SG+SB));
        }
    }
     
    Zuletzt bearbeitet: 17. März 2016
  2. Mareta Dagostino

    Mareta Dagostino Superstar

    Beiträge:
    1.315
    Zustimmungen:
    99
    Punkte für Erfolge:
    49
    Du musst statt mit 255 richtig mit 256 multiplizieren. Statt "llRound(col.x*255)" usw. könntest du zum Beispiel versuchen:
    R = llFloor(col.x * 256);
    if (R == 256) R = 255;
    usw.
    Die if Abfrage ist notwendig, um den Fall abzudecken, dass beim float wirklich mal 1.0000 getroffen wird.

    EDIT: Ganz oben bei der Routine, die den Hex-Wert wieder in dezimal zurückrechnet, hast Du auch noch ein 255 => richtig ist fColorMax= 256.0
     
    Zuletzt bearbeitet: 17. März 2016
  3. Archon Short

    Archon Short Administrator Mitarbeiter

    Beiträge:
    5.147
    Zustimmungen:
    730
    Punkte für Erfolge:
    124
    Danke, dann geb ich dem Ganzen nochmal eine Chance :)
     
  4. Archon Short

    Archon Short Administrator Mitarbeiter

    Beiträge:
    5.147
    Zustimmungen:
    730
    Punkte für Erfolge:
    124
    Das war es nicht, aber ich hab den Fehler gefunden.
    Diesmal ist es dann:
    Code:
    integer     iComponentLength    = 2;
    string      sHexPrefix          = "0x";
    float       fColorMax           = 255.0;
    vector vColorFromHex(string sColor)
    {
            string sX; string sY; string sZ; integer iHelper; vector vColor;
            iHelper = 0;
            sX = llGetSubString(sColor, iHelper, iHelper + iComponentLength - 1);
            iHelper = iHelper + iComponentLength;
            sY = llGetSubString(sColor, iHelper, iHelper + iComponentLength - 1);
            iHelper = iHelper + iComponentLength;
            sZ = llGetSubString(sColor, iHelper, iHelper + iComponentLength - 1);
         
            vColor = <((integer)(sHexPrefix + sX)) / fColorMax, ((integer)(sHexPrefix + sY)) / fColorMax, ((integer)(sHexPrefix + sZ)) / fColorMax>;
            return vColor;
    }
    string to_hex(integer ii)
    {
        if (ii==0) return "00";
        integer i1 = (integer)ii/16;
        integer i2 = (integer)(ii-(i1*16));
        string hexnumbers="0123456789abcdef";
        return llGetSubString(hexnumbers, i1, i1) + llGetSubString(hexnumbers, i2, i2);
    }
    
    default
    {
        state_entry()
        {
            llOwnerSay((string)vColorFromHex("6599db"));
        }
        touch_start(integer honk)
        {
            vector col = llGetColor(2);
            integer R = llFloor(col.x*256);
            integer G = llFloor(col.y*256);
            integer B = llFloor(col.z*256);
            if(R == 256) R= 255;
            if(G == 256) G= 255;
            if(B == 256) B= 255;
            string SR = to_hex(R);
            string SG = to_hex(G);
            string SB = to_hex(B);
         
            llOwnerSay((string)col);
            llOwnerSay("HEX = "+SR+SG+SB);
            llOwnerSay((string)vColorFromHex(SR+SG+SB));
        }
    }
     
    Zuletzt bearbeitet: 17. März 2016
  5. Mareta Dagostino

    Mareta Dagostino Superstar

    Beiträge:
    1.315
    Zustimmungen:
    99
    Punkte für Erfolge:
    49
    Ich sehe jetzt zwar genau die Änderung, die ich oben beschrieb, aber sei's drum, Hauptsache läuft. ;)
     
    Zuletzt bearbeitet: 18. März 2016
  6. Archon Short

    Archon Short Administrator Mitarbeiter

    Beiträge:
    5.147
    Zustimmungen:
    730
    Punkte für Erfolge:
    124
    Die Formel
    integer i2 = (integer)(ii-(i1*16));
    war vorher fälschlicher Weise
    integer i2 = (integer)(ii-(i1*16))/16;
    dadurch war i2 immer 0.
    Kleine Ursache, große Wirkung.

    Inworld hab ich auch wieder zu llRound gewechselt, da es die 3 if-Fragen einspart.

    Im Gegensatz zu den vorher in meinem Projekt verwendeten Vectoren spare ich durch die HEX-Werte eine Menge Platz ein, und kann jetzt alle benötigten Informationen in eine NC-Zeile schreiben, vorher hatten mir da 8 Zeichen gefehlt und jetzt hab ich sogar noch genug Reserve für weitere Parameter.
     
    Zuletzt bearbeitet: 18. März 2016
  7. Mareta Dagostino

    Mareta Dagostino Superstar

    Beiträge:
    1.315
    Zustimmungen:
    99
    Punkte für Erfolge:
    49
    OK, das konnte ich ja nicht ahnen, dass der Fehler schon im ersten Beitrag nicht mehr drin war. Warum llRound die If-Abfragen einspart, erschließt sich mir allerdings nicht: Die Wahrscheinlichkeit für das problematische Zwischenergebnis 256 (was meine If-Abfrage verhindert) ist mit llRound sogar erheblich größer als mit llFloor. Während llFloor zu 256 gleichmäßigen Intervallen führt, sind die Intervalle für Schwarz und Weiß bei llRound unsauber.

    Folgender Trick könnte helfen, die If-Abfragen zu sparen:
    string hexnumbers="0123456789abcdeff";

    Wenn nun i1 wegen des Überlaufs 16 ergibt (256 ist 0x100), dann wird einfach das zweite "f" hinten im String angesprungen.

    ----------------

    Du könntest tatsächlich llRound in Kombination mit dem ursprünglichen Wert 255 nehmen. Das ist allerdings mathematisch falsch, weil dann die Intervalle für "ganz schwarz" und für "ganz weiß" nur halb so groß sind wie die Intervalle der anderen Farben. Durch diese Spreizung wird der Grenzfall 1.0 abgefedert, weil 1.0 * 255 eben gerade 0xFF ist.
     
    Zuletzt bearbeitet: 18. März 2016
  8. Archon Short

    Archon Short Administrator Mitarbeiter

    Beiträge:
    5.147
    Zustimmungen:
    730
    Punkte für Erfolge:
    124
    Naja, ich nehme nun wieder die 255 anstatt die 256, da die Rückumwandlung ja auch über die 255 funktioniert.
    Ich werde mal schauen wie es sich in automatisierten Vergleichen so macht.
    Da stelle ich beide Varianten gegeneinander und lasse mir nur bei unterschiedlichen Ergebnissen die Vector und HEX Werte ausgeben.
     
  9. Mareta Dagostino

    Mareta Dagostino Superstar

    Beiträge:
    1.315
    Zustimmungen:
    99
    Punkte für Erfolge:
    49
    Ich denke nicht, dass Du optisch irgendwelche Unterschiede siehst. Ist eher eine Frage des Prinzips und der Mathematik. Insbesondere, wenn Deine Vektoren ursprünglich eh RGB Hexwerte waren, gibt es keinen Unterschied. Relevant wird das nur, wenn die Vektoren als Ergebnis irgendeiner Rechenoperation entstehen, wie Veränderung der Helligkeit, Farbsättigung oder sowas.
     
    Zuletzt bearbeitet: 18. März 2016
  10. Archon Short

    Archon Short Administrator Mitarbeiter

    Beiträge:
    5.147
    Zustimmungen:
    730
    Punkte für Erfolge:
    124
    Es sind Farbwerte, die einmalig abgefragt werden.
    Später müssen sie jederzeit wieder gesetzt werden können.

    Wichtig ist aktuell halt nur, daß die Vektoren für die Farbwerte einfach zu viel Platz eingenommen hatten, was nun erledigt ist.