2013.01.30.
13:54

Írta: harsanyireka

Stringek, kirajzolt szövegek, transzformációk

A String osztály

Már használtunk stringet pl. képfájl betöltésére vagy szöveg kiírására, ezek kódjai:

println("printing some text to the message window!");  
PImage img = loadImage("filename.jpg");                

A string karaktert vagy karakterláncot jelent. A karakterek értéket is tárolnak, tehát a string is adat. 

         

Ha nem lenne string osztályunk akkor ilyen kódot kellene írnunk:

char[] sometext={'H','e','l','l','o',' ','W','o','r','l','d'};

De mivel Processingben van, ezét a következő formát használhatjuk:

String sometext = "How do I make String? Type some characters 
between quotation marks!"; //a kódot egy sorba írd!

Különböző metódusokkal működik:

  

charAt()

Szimpla karater ad vissza, az index szám jelöli hogy a stringnek hanyadik elemét akarjuk kiolvasni. Arra vigyázz hogy az első elemet 0-val, a másodikat 1-gyel stb. lehet elérni!

String message = "some text here.";
char c = message.charAt(3);
println(c);                // az eredmény: 'e'

  

length()

Nem összekeverendő a tömbb hossz paraméterével. A kerek zárójel is arra utal hogy ez nem egy paraméter hanem egy függvény.

String message = "This String is 34 characters long.";
println(message.length());

      

toUpperCase(), toLowerCase() 

Átváltoztathatjuk a stiongünket nagybetűkre és kisbetkre ezekkel.

String uppercase = message.toUpperCase();
println(uppercase); 

Mivel a string egy állandó, tehát értéke nem változik, ezért ha változtatni akarjuk akkor mindig létre kell hoznunk egy új stringet. Ebben a példában a a  toUpperCase a sting negybetűs másolatát küldi vissza.

      

equals()

== operátorral tehetjük a stringet valamivelegyenlővé, a szimpla = deklarálásra szolgál!

String one = "hello";
String two = "hello";
println(one == two);

A harmadik sorban az objektumok memória címét hasonlítjuk össze (technikailag), mivel ugyanazta stringet tartalmazzaa kétérték megegyezik, egyébként a végeredmény hamis (false) lenne.  

Az equal() függvény biztosítja hogy leellenőrizhessük hogy a két string ugyanazt a karakterláncot tartalmazza-e, figyelmen kívül hagyva hogy hol tároljuk az adatot.

String one = "hello";
String two = "hello";
println(one.equals(two));

Habár mindkét kód ugyanazt csinálja, biztonságosabb az equalt() használni, mivel attól függően hogy a kódban hol hozzuk létre string objektumot, az == nem mindigműködik. 

Stingeket egymáshoz is fűzhetünk a + operátorral, számok esetében ez természetesen összeadást jelent. 

String helloworld = "Hello" + "World";

Változókat is hozzá fűzhetünk stringekhez:

int x = 10;
String message = "The value of x is: " + x;

                         

Szöveg megjelenítése

Ennek legegyszerűbb modja hakiprinteljük őket az üzenet ablakban. Ezt csináljuk amikor nyomon akarjuk követni az adatunkat, pl. ha a horizontális egérmozgást akarjuk tudni akkor ezt írjuk le:

println(mouseX);

De akár leíró szöveget is kiírhatunk a kódban általunk gondolt helyen:

println("Kiírjuk az egér pozícióját!");

        

Ebben az esetben a szövegünk még nem a megjelenítő ablakban van, hogyan tudnánk ezt is elérni? A következő pár lépéssel:

1. Deklaráljunk egy PFont típusú objektumot.

PFont f;

2. Hozzuk létre a betűket a nevére hivatkozva a createFont() függvénnyel. Ez ugyanúgy egyszer fut le minta setup(). Éppúgy mint a képeknél, memóriába töltjük az adatot, tehát nem célszerű draw() függvénbe tenni. 

Az elérhető rendszer-betűtipusokat (mindenkinek van, nem kell telepíteniük) egy kóddal ki tudod printelni, ezután innen tudsz választani:

size(200, 200);
String[] fontList = PFont.list();
println(fontList);

Ezután a következő szintaxissal tudod alkalmazni a betű-nevedhez a paramétereket: típus, mérte, anti-alising legyen (true) vagy ne (false):

f = createFont("Arial",16,true); 
// Arial, 16 pont, anti-aliasing be

3. Specifikáld a betűt a textFont() segítségével, két paramétere van, a betű-változód neve és a mérete (utóbbi opcionális és változtatható). Ez a sima text()-hez képest egy bitmap képet eredményez, így dinamikusan növelhető aszöveg mérete. P2D render használatával feljavíthatod a kép minőségét és teljesítményt is. A P3D render pixeleket eredményezhet.

textFont(f,36);

4. Szín megadása fill()-lel:

fill(255);

5. A szöveget a text() függvény meghívásával tudjuk megjeleníteni. Három paraméterrel rendelkezik, éppúgy mint a formák: a megjelenítendő szöveg, x és y koordinátaák.

text("Hello Strings!",10,100);

               

A teljes kód:

sting1.jpg

PFont f;                          
  
void setup() {
  size(200,200);
  f = createFont("Arial",16,true); 
}

void draw() {
  background(255);
  textFont(f,16);                 
  fill(0);                        
  text("Hello Strings!",10,100); 
}

   

Menüből is létrehozhatunk betűt: "Tools" --> "Create Font." Ez létrehoz egy  VLW betű fájlt a data mappádban, amit PFont objektumba be tudsz tölteni loadFont() függvénnyel.

f = loadFont("ArialMT-16.vlw");

     

Szöveg animálása

Nézzünk meg néhány hasznos függvényt a fentiek mellé!

   

textAlign()

A sortördelést határozhatjuk meg vele: balra zárt (LEFT), középre zárt (CENTER) és jobbra zárt (RIGHT).

PFont f;

void setup() {
  size(400,200);
  f = createFont("Arial",16,true); 
}

void draw() {
  background(255);

  stroke(175);
  line(width/2,0,width/2,height);

  textFont(f);       
  fill(0);

  textAlign(CENTER);
  text("This text is centered.",width/2,60); 

  textAlign(LEFT);
  text("This text is left aligned.",width/2,100); 

  textAlign(RIGHT);
  text("This text is right aligned.",width/2,140); 

               

textWidth()

Kiszámolja és visszaküldi egy karakter vagy szöveg string szélességét.

Csináljuk egy balról jobbra mozgó feliratot! Ha tudjuk a kezdőpont x koordinátáját és a szöveg szélességét, valamint az ablakunk méretét, akkor ki tudjuk számolni az animáció végének x koordinátáját, ahol méglátszik a teljes szöveg. 

Először setup()-ban inicializáljuk a szöveget, betűtipust és méretet, x és y koordinátát:

// Főcim animálása
String headline = "Akármi lehet a főcím";
PFont f;  // globális változó: f
float x;  // szöveg vzsintes pozíciója

void setup() {
  f = createFont("Arial",16,true);  // betű betöltése
  x = width; // inicializáljuk a szöveg jobb szélét
}

A draw()-ban megjelenítjüka szöveget az adott helyen:

textFont(f,16);        
textAlign(LEFT);
text(headline,x,180); 

Változtatjuk az x pozició értékét hogy létrejöjjön az animáció, mivel balra kell csússzon az értéket csökkentjük:

x = x - 3;

Most egy kicsit bonyolultabb rész jön. Mivel a szövegünk balra van zárva, ezért nem elég ha x kisebb mint 0 egyenlettel akarjuk eltűntetni az ablakból (mint formáknál) mivel ilyenkormég egy része belóg a képe. Ehelyett az egyenletünk úgy néz ki hogy x kisebb mint a nullából kivont szöveg-szélesség (alább a kód):

float w = textWidth(headline);
if (x < -w) {
  x = width; 
}

   

A teljes kód:

sting2.jpg

// string tömbbe tesszük a szöveget:
String[] headlines = {
  "Processing a köbön", 
  "Akármi lehet a főcím",
  };

PFont f;  // f globális betű változó
float x;  // szöveg vizszintes helyzte
int index = 0;

void setup() {
  size(400,200);
  f = createFont("Arial",16,true);  
  // jobboldali szöveg eltűntetés inicializálása
  x = width; 
}

void draw() {
  background(255);
  fill(0);

  // szöveg megjelenítése x poziciónál
  textFont(f,16);        
  textAlign(LEFT);
  text(headlines[index],x,180); 

  // animáció sebessége:
  x = x - 3;

  // ha x kisebb minta negatv szélesség 
  // tűnjön el a szöveg:
  float w = textWidth(headlines[index]);
  if (x < -w) {
    x = width; 
    index = (index + 1) % headlines.length;
  }
}

   

Ezeken kívül még a  textLeading()textMode()textSize() függvények tartoznak a témához. 

                  

Szöveg forgatása

Transzformációt és forgatást is érvényesíthetünk szövegre. Tanslate() használatakor a koordinátarendszerünket helyezzük alrébb, így a fomra x,y értéke ugyanaz maradhat:

grid moved with arrow showing motion

A pushMatrix() és popMatrix() függvényekkel jelezzük hogy a transzformációt melyik parancssorokra akarjuk értelmezni (amennyiben nem az egész kódra akarjuk). A példában a kirajzolt szürke négyszöget eltoljuk translate()-tel ráccsal együtt 60,80 koordinátához és kékre színezzük, amint látod ennek helye megegyezik a másodiknak kirajzolt piros négyzettel, amit az eredeti koordinátarendszerben rajzoltunk ki, csak a kezdőpontját helyeztük át, mivel minkét négyszög elfás,a színeik összekeverednek, így egy lila jön létre:

string3.jpg

void setup()
{
  size(200, 200);
  background(255);
  noStroke();

  // eredeti szürke négyzet kirajzolása:
  fill(192);
  rect(20, 20, 40, 40);
  
  // az átlátszó piros nyégyzet megváltoztatott koordinátával: 
  fill(255, 0, 0, 128);
  rect(20 + 60, 20 + 80, 40, 40);
  
  // az átlátszó kék négyzet a rács alrébb tolásával:
  fill(0, 0, 255, 128);
  pushMatrix();
  translate(60, 80);
  rect(20, 20, 40, 40);
  popMatrix();
}

 A forgatás ugyanígy működik, paraméternek megadjuk hogy milyen mértékegységben és mennyivel akarjuk forgatni:

  pushMatrix();
  rotate(radians(45));
  fill(0);
  rect(40, 40, 40, 40);
  popMatrix();

 Nagyítás vagy kicsinyítés:

  pushMatrix();
  scale(2.0);
  rect(20, 20, 40, 40);
  popMatrix();

 

Az előzőek alapján forgassuk körbe a középpont körül a középre igazított szövegünket:

string4.jpg

PFont f;
String message = "ez a szöveg pörög";
float theta;

void setup() {
  size(200, 200);
  f = createFont("Arial",20,true);
}

void draw() { 
  background(255);
  fill(0); 
  textFont(f);                     // szöveg beállítása
  translate(width/2,height/2);    // középre transzformálása
  rotate(theta);       // elforgatása theta-változó értékével
  textAlign(CENTER);            
  text(message,0,0);            
  theta += 0.05;                // forgatás növelése
}

     

Szöveg kirajzolása karakterenként

Ebben az esetben a karaktereket egyenként mozgathatod, színezheted, stb. Ehhez létre kell hoznod egy tömbböt amibe beolvasod a karaktereket egyenként charAt() függvénnyel, és innen fogod őket kirajzolni úgy hogy a pozíciójuk x tengelyen mindig 10-zel több. A fent említett módokon hozd létre a PFont objektumodat, töltsdbele a szöveget, határozd meg aszöveg tulajdonságait és draw()-ba írd a karakter számláló for ciklust!

PFont f;
String message = "Each character is not written individually.";
void setup() {
size(400, 200);
f = createFont("Arial",20,true);
}
void draw() { 
background(255);
fill(0);
textFont(f);
// egy tömbként jelenik meg a szöveg
text(message,10,height/2);
}

Ebben az esetben egyben jelent meg a szöveged, mivel nincs kiolvasva karakterenként. Írjuk át:

PFont f;
String message = "Each character is written individually.";
void setup() {
size(400, 200);
f = createFont("Arial",20,true);
}
void draw() { 
background(255);
fill(0);
textFont(f);

int x = 10; 
for (int i = 0; i < message.length(); i++) {
// i++ ugyanaz mint i=i+1 // charAt() egyesével beolvassa a karaktereket: text(message.charAt(i),x,height/2); // 10 pixelközönként kiírja a karaktereket: x += 10; }

}

Ebben az esetbenmár karakterenkéntírtuk ki a szöveget,de nagyon szétesik, igazítsuk meg textWidth() fügvénnyel, ami kiolvassa az adott karakter (i változóval meghatározott) szélességét (pixelben) és hozzáadja az x-hez (ami10 pixel):

PFont f;
String message = "Each character is written individually.";

void setup() {
  size(400, 150);
  f = createFont("Arial",20,true);
}

void draw() { 
  background(255);
  fill(0);
  textFont(f); 
int x = 10; //első karakter itt lesz
//kiolvassuk a karaktereket sorban egy for ciklussal:
// for (int i = 0; i < message.length(); i++) { textSize(random(12,36)); // 12-36 közötti random érték text(message.charAt(i),x,height/2); // textWidth() a betűköz helyes beállítására: x += textWidth(message.charAt(i)); } noLoop(); }

       

Most már tudjuk effektezni is a karaktereket egyenként! Akövetkező példában, ha nyomva tartod a bal egér gombot, akkor összerázódnak a betűk, azaz pozíciót változtatnak:

PFont f;
String message = "click mouse to shake it up";
// Letter objektum tömb, letters névvel:
//Az osztályt később meghatározzuk majd! Letter[] letters; void setup() { size(260, 200); // betű betöltése f = createFont("Arial",20,true); textFont(f); // adott string hosszúságú tömbb létrehozása: letters = new Letter[message.length()]; // Letters inicializálása x pozícióra int x = 16; for (int i = 0; i < message.length(); i++) { letters[i] = new Letter(x,100,message.charAt(i)); x += textWidth(message.charAt(i)); } } void draw() { background(255); for (int i = 0; i < letters.length; i++) { // betűk megjelenítése letters[i].display(); // ha egérgomb nyomva, a betűk rázkódnak // ha nincs,akkor eredetipozícióba kerülnek if (mousePressed) { letters[i].shake(); } else { letters[i].home(); } } } // Az osztály ami minden egyes betűre jellemző class Letter { char letter; // jegyezze meg az eredeti pozícióját: float homex,homey; // és a pillanatnyit is: float x,y; Letter (float x_, float y_, char letter_) { homex = x = x_; homey = y = y_; letter = letter_; } // betűk megjelentése void display() { fill(0); textAlign(LEFT); text(letter,x,y); } // mozgasd a betűket random void shake() { x += random(-2,2); y += random(-2,2); } // kerüljenek vissza a betűk eredeti pozícióba void home() { x = homex; y = homey; } }

       

A karakterről karakterre módszer lehetővé teszi hogy görbére illesszük a szöveget. Első lépésként fűzzünk fel négyzeteket egy körvonalra, ehhez trigonometriát kell alkalmaznunk. 

 

Példa:

PFont f;
// A kör sugara:
float r = 100;
// a dobozok szélessége és magassága:
float w = 40;
float h = 40;

void setup() {
  size(320, 320);
  smooth();
}

void draw() {
  background(255);
  
  // Rajzoljunk egy kört az ablak közepére
  translate(width / 2, height / 2); //eltoltuk a rácsot
  noFill();
  stroke(0);
  // Az ablakunk közzépontj a köré is,
// innen rajzolunk r sugarú kört: ellipse(0, 0, r*2, r*2); // 10 dobozunk legyen: int totalBoxes = 10; // Visszakövetjük a pozíciójukat a görbe mentén: float arclength = 0; // for ciklus az összes dobozhoz: for (int i = 0; i < totalBoxes; i++) { // a dobozok felének szélességével toljuk el őket: arclength += w/2; // A fok radiánban megadva,
// a pozíció osztva a sugárral: float theta = arclength / r; pushMatrix(); // derékszögű koordináta átalakítása: translate(r*cos(theta), r*sin(theta)); // doboz elforgatása: rotate(theta); // doboz megjelenítése: fill(0,100); rectMode(CENTER); rect(0,0,w,h); popMatrix(); // ismét elmozdítjuk a dobozt: arclength += w/2; } }

Ezek után a dobozokon belülre helyezzünk egy-egy betűt. Mivel a betűk szélessége változó ismét a textWidth()-et hívjuk segítségül.

// A megjelenítendő szöveg:
String message = "text along a curve";

PFont f;
// a kör sugara:
float r = 100;

void setup() {
  size(320, 320);
  f = createFont("Georgia",40,true);
  textFont(f);
  // Középre zárjuk a szöveget:
  textAlign(CENTER);
  smooth();
}

void draw() {
  background(255);

  // középre toljuk a koordináta rendszert:
// kört rajzolunk: translate(width / 2, height / 2); noFill(); stroke(0); ellipse(0, 0, r*2, r*2); // Visszakövetjük a pozíciót a görbe mentén: float arclength = 0; // For ciklus az összes dobozhoz: for (int i = 0; i < message.length(); i++) { // leellenőrizzük minden karakter szélességét: char currentChar = message.charAt(i); float w = textWidth(currentChar); // alrébb tesszük a dobozok szélességével: arclength += w/2; // radiánsban megadott szög:
// dobozok szélessége osztva a kör sugarával: // a kör bal szélén kezdjük, PI-től indul: float theta = PI + arclength / r; pushMatrix(); // derékszögű koordináta átalakítása: translate(r*cos(theta), r*sin(theta)); // doboz elforgtása: rotate(theta+PI/2); // 90 fokkal elforgatjuk // karakter megjelenítése fill(0); text(currentChar,0,0); popMatrix(); // eltolása a megfelelő pozícióhoz: arclength += w/2; } }

 

A fokok PI-vel meghatározott értékei:

          

forrás: http://processing.org/learning/text/

http://processing.org/learning/transform2d/ 

http://processing.org/reference/pushMatrix_.html

 

 

 

Szólj hozzá!

A bejegyzés trackback címe:

https://processing.blog.hu/api/trackback/id/tr455031953

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.
süti beállítások módosítása