0

I’d like to program a game in processing (Java) in which the player draws a possibly curved line and next makes a dot on this line. I think, I would draw the line only with pixels, not lines oder bezier-curves and maybe store the drawn pixels in an ArrayList. But there are 2 problems I'm not sure how to solve fast:

a) The line must not cross itself or any other existing line. This would mean, I have to check during the drawing if the currently drawn pixel is already stored in the ArrayList.

b) The player must place a dot or small circle somewhere on its last drawn line and only on this one. So may be I should use additionaly an ArrayList for every drawn line? And every Line consist of an ArrayList of pixels?

Are there any classic approaches to doing it somehow efficiently? Are there any mathematical approaches?

Thanks in advance, Ingo

Any tips on a suitable data structure, mathematics or source code would be great.

Addition: I tried working with only the pixels, but I get only holes where the lines intersect:

void setup() {
  size(600, 400);
  background(0);
  stroke(255);
  strokeWeight(3);
}

void draw() {}

void mouseDragged() {
  if (pmouseX!=0&&pmouseY!=0) {
    loadPixels();
    int i=(mouseY-1)*width+mouseX;
    if (brightness(pixels[i])==0) {
      line(pmouseX, pmouseY, mouseX, mouseY);
    }
  }
}

Ingo
  • 1
  • 1
  • "I think, I would draw the line only with pixels, not lines oder bezier-curves and maybe store the drawn pixels in an ArrayList" - any reason not to store the parameters of the curve? I'd expect it to be simpler to calculate "how close is the given pixel to the last drawn curve" than to check every individual pixel. (And that way you don't get into issues of precision, anti-aliasing etc.) – Jon Skeet Mar 11 '23 at 07:23
  • If what you are doing is a "game" then that implies rules and user interaction. I'd get it to be able to run through it's processes required by some limited terms under control of the users controls before trying to find fast optinised ways of coding. – Samuel Marchant Mar 11 '23 at 08:12

1 Answers1

0

a) The line must not cross itself or any other existing line. This would mean, I have to check during the drawing if the currently drawn pixel is already stored in the ArrayList.

The simplest solution to that would be to store all pixels in a bitmap, so you can look at that to learn whether a pixel is already coloured. Either use the same memory that's also used for rendering the lines, or a separate BufferedImage just for this purpose. If you make that black and white you can get 8 pixels into a byte, which might help with cache efficiency.

Note that if your line drawing algorithm does diagonal jumps, then you might still have two lines crossing each other without sharing any pixels. Like this:

    2      1111
     211111
 111112
1     2

So in that case you might want to look around during a diagonal connection, and reject it if both of the pixels of the opposite diagonal are already coloured.

b) The player must place a dot or small circle somewhere on its last drawn line and only on this one. So may be I should use additionaly an ArrayList for every drawn line? And every Line consist of an ArrayList of pixels?

That's one option. Another option would be to have a second buffered image just for the pixels of the current line. In cases where the line comprises many pixels but only a small neighborhood is candidates for the circle placement, this would make finding the nearest a bit cheaper. The benefit would be cancelled by the overhead needed to manage that extra picture, though, so it would be most useful if you need multiple circles placed between line drawings.

Are there any classic approaches to doing it somehow efficiently?

General technique might be to not be afraid of duplicate data. If representing the same information as a list of positions is better for some tasks, and as a black and white image better for others, then feel free to have both and make sure to keep them in sync, unless that in itself is more costly than the gains from the second data structure.

Are there any mathematical approaches?

There is things you could use for finding nearest points. Quad trees come to mind. But that feels like overkill for your user case. If you decide to go for a parameterized description of your lines instead of pixels then expressing their intersections would definitely be amenable to mathematical considerations. A simple thing like an orientation predicate that can tell you whether three points are arranged in a clockwise or counterclockwise order can go a long way in checking for intersection of line segments.

MvG
  • 57,380
  • 22
  • 148
  • 276
  • I tried working with the pixels and checking simply for brightness. The only problem is, that the line only gets a hole where it intersects with the old line. Next problem: I'm thinking about playing against the computer and I have absolutely no idea how to generate such an line. (I put my test-code into the question). – Ingo Mar 11 '23 at 15:29