0

The goal of the below code is to take a given text, and break the text into categories based on the length of each word. I have achieved this basic function, as the current code successfully places all the one-letter words into a column, all the two-letter words into a column, etc. However, in order to bump each word in each column below the previous one, I must assign a unique y-variable to each if statement. However, this is problematic because I want to keep track of each y position in order to draw lines connecting the sequential order of the words as they are in the sample text. Perhaps there is a better overall approach -- or perhaps there is a way to draw lines between sequential words without creating one global "y" value....

String text = "this is will only have a two word form as I want to see if this can work";
String[] words = split(text, " ");

size(200, 200);
background(#FFFFFF);

int a = 30;
int b = 30;
int c = 30;
int d = 30;

int x = 10;

for (int i = 0; i < words.length; i++) {

  textSize(10);
  fill(0);

  if (words[i].length() == 1) {
    text(words[i], x, a);
    a = a + 13;
  }

  if (words[i].length() == 2) {
    text(words[i], x+30, b);
    b = b +13;
  }

  if (words[i].length() == 3) {
    text(words[i], x+60, c);
    c = c +13;
  }

  if (words[i].length() == 4) {
    text(words[i], x+90, d);
    d = d +13;
  }

 // I want to draw a line during each iteration in order to connect the sequential order of the words
 //line(x, y, px, py)

}
4

2 回答 2

1

Fascinating problem! I think I have an understanding of what you want to do, but it's a little scary to approach this one. In trying to write a sketch to solve this I discovered that it's difficult to calculate the y value for the strings. The x value can be calculated by the length of the string without any issue, but the y value isn't that easy because there can be any number of strings with that length.

So I was going to say I'd use a HashMap where I have the y-values as keys and the strings as values, but then I realized that they aren't necessarily unique. It seems like you're a beginner so I don't want to overwhelm you, but the solution I have in mind uses classes.

I would create a class and create an array of that object to store the Strings with x's, y's, indices, and values.

Here's my attempt:

final String text = "this is will only have a two word form as I want to see if this can work";

PFont font; //this is the font I'm gonna use to draw with later
Word[] words; //this is where I'll store my sentence later


//this is a basic CLASS. I can create instances of it later and store things inside it
class Word
{
  String value;
  int    index;
  float  x, y;

  Word(String value, int index)
  {
    this.value = value;
    this.index = index;
    //we're not gonna set x and y in here, we'll calculate that later
  }

  int length() { return value.length(); }
}

//this is where I'll give all my variables values
void setup()
{
  String[] sentence = split(text, " ");
  words = new Word[sentence.length];

  //initially all the words are in order, so we'll store these i values as indices
  for(int i=0;i<sentence.length;i++)
    words[i] = new Word(sentence[i], i);

  size(300, 300);

  font = createFont("arial",18);

  //sort the list by word length
  sortList();

  //find the x and y coordinates of each word in the list
  findCoordinates();
}

void sortList()
{
  //here I sort the list of words using a basic bubble sort
  boolean flag = true;
  while(flag)
  {
    flag = false;
    for(int i=0;i<words.length-1;i++)
    {
      if(words[i].length() > words[i+1].length())
      {
        //swap the two
        Word word = words[i];
        words[i] = words[i+1];
        words[i+1] = word;

        flag = true;
      }
    }
  }
}

void findCoordinates()
{
  float y = 50;
  for(int i=0;i<words.length;i++)
  {
    //I noticed that there was a relationship between the length of words
    //and their x position, so I wrote this formula for it
    float x = 30+40*(words[i].length()-1);

    //I used the global y like you did. If the length of the current word
    //is different than the previous one, then reset the y
    if(i!=0 && words[i].length() != words[i-1].length())
      y = 50;

    //since we now know the x and y of the word, save it!
    words[i].x = x;
    words[i].y = y;

    //and we'll increment y since the next word will be below this one
    y += 18;
  }
}

//this helps me later when I draw the lines, so I can do it in their original order
Word getWordAt(int index)
{
  //goes through the list and finds the one with specified index
  for(int i=0;i<words.length;i++)
    if(words[i].index==index)
      return words[i];

  return null;
}

//this is where I'll draw the lists on the screen
void draw()
{
  background(255);
  textAlign(CENTER,CENTER);
  textFont(font);
  fill(0);

  //let's print the words to the screen now
  for(int i=0;i<words.length;i++)
  {
    text(words[i].value, words[i].x, words[i].y);
  }

  //and over here, let's draw the lines!
  for(int i=0;i<words.length-1;i++)
  {
    line(getWordAt(i).x, getWordAt(i).y, getWordAt(i+1).x, getWordAt(i+1).y);
  }
}

It's a big and interesting problem, and it's a little scary to be honest, but that's how I'd organize it! There's not really a better way to do this. I have another sketch where I did it without classes, but it gets a little messy.

I hope that this makes sense and you learn something from it. Happy programming!

于 2013-10-29T16:51:31.913 回答
0

I would add all the words to Lists according to their length instead of immediately drawing them (or a list of list if you also would like to have a dynamic amount of collumns).

Then you can calculate their y position based on their index in the list and do not have to store the y position for every loop in a variable. Afterwards you can then draw your lines.

A list is kinda lika an array but vith variable length. So you would make either a list for every wordlength (one for words with one letter one for words with two etc.) these represent your collumns or you would make a list that contains all these "collumn"-lists so you can add them dynamically. Documentation on List can be found here or you google for java list there will be thousands of helpfull links on working with lists.

In these lists your words get stored sequentially and get assigned an index (like tha index in an array). Now you made every word 13px high so the y position of every word in the list is 13 * index. After you have added your whole sentence into the lists you traverse the lists and draw your lines from one word to the next. I hope this is enough.

于 2013-10-29T06:56:27.137 回答