this post was submitted on 13 Jan 2025
26 points (96.4% liked)

Learn Programming

1683 readers
22 users here now

Posting Etiquette

  1. Ask the main part of your question in the title. This should be concise but informative.

  2. Provide everything up front. Don't make people fish for more details in the comments. Provide background information and examples.

  3. Be present for follow up questions. Don't ask for help and run away. Stick around to answer questions and provide more details.

  4. Ask about the problem you're trying to solve. Don't focus too much on debugging your exact solution, as you may be going down the wrong path. Include as much information as you can about what you ultimately are trying to achieve. See more on this here: https://xyproblem.info/

Icon base by Delapouite under CC BY 3.0 with modifications to add a gradient

founded 2 years ago
MODERATORS
 

How can I define lines so when I click on the screen, my program knows whether I clicked on A B or C?

top 10 comments
sorted by: hot top controversial new old
[–] [email protected] 11 points 1 week ago (3 children)

My approach would involve using some kind of polygon library. When you draw lines, you're really defining polygons within your canvas. In the case of regions B and C, the edge of the screen make up the rest of the polygon.

Once you have your polygons defined, you can compare the coordinates of the click event to the polygons. With a good library, it should be fairly trivial to check if a point is within a polygon.

In the case of region A, you'd find that a click is inside both region A and region B, so I guess I'd also check to see if there are multiple polygons a click could be inside. If there are, then you need to also see if a polygon is inside another polygon to determine the specific polygon clicked. This is also made much simpler by using a good library

[–] [email protected] 7 points 1 week ago

Adding to this: if you can’t use a polygon library, it’s quite easy to check if a point is inside a polygon. Just count the number of polygon edges is above the point (have a separate count for each polygon).

If the number is odd, then the point is inside the polygon. If it’s even, then it’s outside.

If there are multiple candidate polygons (which will happen with A in the example), pick the one with the closest edge to the point. Alternatively, pick the smallest polygon.

See ray casting algorithm in this page: https://en.wikipedia.org/wiki/Point_in_polygon

Just beware of floating point precision when implementing the algoritm.

But use a polygon library first and foremost.

[–] [email protected] 6 points 1 week ago* (last edited 1 week ago)

Good answer! I can't recommend a library right now, but I recommend looking into the geometric term "Point in Polygon" to further read about this task/problem.

Edit: wanted to clarify that I just wanted to give a better keyword for OP to search for a solution.

[–] sip 5 points 1 week ago

I do want to mention this is a rabbit hole, as a U shaped polygon can be tricky to check. so I strongly suggest using a library for checking point in polygon.

[–] [email protected] 9 points 1 week ago

The long way is point in polygon: https://en.wikipedia.org/wiki/Point_in_polygon

If you're using web, the easy way is use SVG

[–] [email protected] 5 points 1 week ago (1 children)

what environment is this? where is this going to be used?

[–] [email protected] 4 points 1 week ago

Seriously! How can we even make a suggestion without knowing some basic info like language or API. Even ancient Win32 (using C, C#, or VB6) has the ability to create regions and test to see if a given point is inside a specific region.

[–] ulterno 4 points 1 week ago

One simple way should be to "colour" the areas as A,B,C ^[Using an algorithm similar to what the Fill Paint tools use]. Assuming you are working with a bitmap, just use a 1:1 2d char array to represent it, with the values in each cell corresponding to each pixel in the image. You can then check the value corresponding to the point that was clicked. This can be simplified by instead mapping it 1.5:1 or 2:1 or further, depending upon your requirement.

Another way: If you are using an SVG, you are probably going for lower RAM usage and don't want an array as big as the image dimensions, in which case, you will have to assign sides of every separate path (border). Then whenever there is a click, you can calculate where it lies WRT each path. This would be more useful if the number of paths is low, but you care more about user clicking very close to the borders and you are using higher precision when calculating the position. But having too many border paths will make the computation time longer, while at least keeping the total RAM usage low.


Please note, I have never implemented a solution to this before and just gave the first solution I came up with, that I thought, could be done using C++. You might want to wait for ppl with higher XP to give their answers, or if this is a competition problem, their recommended answer.

[–] [email protected] 3 points 1 week ago

Best i can conceive with so little context of language usage or other information is something like this:

https://stackoverflow.com/questions/55893187/python-tkinter-canvas-class-inheritance

[–] [email protected] 2 points 1 week ago

Sort the shapes front to back. For each shape you check whether the point is inside or not:

Check for intersections between each edge of the shape, and an edge running from the point you're testing to infinity in any direction. For example 10000 units along the x axis. If the total number of intersections is odd, then the point is inside the shape.