• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
This question was closed Oct 10, 2013 at 11:00 AM by verenion for the following reason:

The question is answered, right answer was accepted

avatar image
2
Question by verenion · Oct 09, 2013 at 12:22 PM · c#linerendererpaths

Merge paths

I have a list of circular paths as an array of Vector3s. These circles highlight an area AROUND two (or more) objects.

alt text

As the image shows, I have this working fine. However, I need a way of "merging" these paths together to form ONE path around all of the objects. Like the second image shown

alt text

I was thinking, one way of doing this, could be to use a sphere collider to check whether any of the nodes are within the sphere (from each objects) and then delete those nodes, leaving the outer nodes to render the line. This seems very messy and lots can go wrong. I am going to use something like LineRenderer to render the line, so it wont have to calculated on each frame (as these are static objects).

untitled-1.png (50.7 kB)
untitled-2.png (51.5 kB)
Comment
Add comment · Show 10
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image vexe · Oct 09, 2013 at 12:56 PM 1
Share

do the points share the same height?

avatar image vexe · Oct 09, 2013 at 01:18 PM 1
Share

of course, you only care about cases where the two circles intersect/touch each other, right? - And will you ever have your circles each have its own radius, or will you always use a shared one?

avatar image raimon.massanet · Oct 09, 2013 at 01:33 PM 1
Share

Project all points to zero-height, and apply the ray casting solution I mentioned below. Then re-apply original height to resulting points. Assuming a terrain point only has one height, the solution is still valid.

avatar image verenion · Oct 10, 2013 at 10:56 AM 1
Share

This was my result. "BaseExpanders" is a class that is attached to each game object, it uses basic sin/cos to create several points on a circle around the object. It then stores those points.

AllPoints is a collection of all of the points from all of the 'expanders'.

 public bool IsPointInCircle (Vector2 center, float radius, Vector2 position)
     {
 
         // Calculate the offset vector from the center of the circle to our position
         Vector2 offset = center - position;
 
         // Calculate the linear distance of this offset vector
         float distance = offset.magnitude;
     
         
         if (radius < distance) {
 
             // If the distance is more than our radius then the point is outside of the circle
             
             return false;
 
         }
         
         return true;
 
     }

 // we then iterate through each circle, so that we are testing each point against each circle
     foreach (BaseExpanders ex in expanders) {
         
         // create the data for this 'circle'
         Vector2 centre = new Vector2 (ex.transform.position.x, ex.transform.position.z);
         float radius = ex.BaseRadius - .1f;
     
         
         // now we have all the points (from both circles), iterate thorugh those
         foreach (Transform point in AllPoints) {
         
             // we need to check if this point belongs to this circle, if so, ignore it, as points belonging to this
             // circle should never be destroyed., only other circles.
             if (point.parent != ex.transform) {
             
                 Debug.DrawLine (point.position, ex.transform.position, Color.white);
                 
                 Vector2 v2p = new Vector2 (point.position.x, point.position.z);
                 

                 // if point is in circle, delete it.
                 if (pointUtil.IsPointInCircle (centre, radius, v2p)) {
                     // not in circle, so don't add tolist
                     point.renderer.material.color = Color.red;
                 } else {
                     BoundaryPoints.Add (point);
                     point.renderer.material.color = Color.blue;
                 }
                 
             }
                 
         }
             
             
             
     }

alt text

screenshot_1.jpg (37.3 kB)
avatar image vexe · Oct 10, 2013 at 11:03 AM 1
Share
  • Looks very nice! Glad you sorted it out.

Show more comments

2 Replies

  • Sort: 
avatar image
4
Best Answer

Answer by vexe · Oct 09, 2013 at 02:01 PM

I upvoted this question because I really like it. I imagine there's a lot of ways to solve this, you could go all mathy about it, and solve circle equations, intersections and whatnot.

Or (I think a simpler way, not necessarily the best) would be to use raycasting (even a linecast would work) as @raimon.massanet said (I'm not sure if this is what he had in mind), my idea is, to let each of those objects scan its surrounding area just like a radar, the length/distance of how further away from your object you'd scan, is r - delta: r is the radius of the circle, delta is a small value. If the scanner ray ever detect a point, you nuke that point because it definitely doesn't belong to the current circle (since it's inside its radius), but to another circle. Do the same for all the other objects.

This will work for any number of circles, regardless of the circles' radius. But first, again you'd have to project everything to 0 height as per the previous comment from raimon.

Here's an illustration using the best drawing tool ever exist (MS Paint) - (I think MS now lets you download a trial version)

alt text

In the first state there's no intersection, nothing's happening. In the 2nd, 3 circles intersect, the scratches indicate points that have been deleted, because they're inside the circle's radar. Notice how the ray/line scanner doesn't reach the circle's area, it's slightly less than its radius.

Also, in order for your ray/line to detect the points, they can't be just a Vector3 or else there's nothing to detect, they have to be gameObjects I believe, you could make a Point class, have it inherit from MonoBehaviour and all it has is a Vector3 property representing its position (returns transform.position)

If you're a circle, How can you tell if a point is inside you? Simple, if the distance between you and that point is less than your radius.

I've put some simple equations, on where you'd have an intersect between 2 circles, when there's none, etc in the awesome MS Paint draw as well (`dist` is the distance between two circles, r1 is the radius of circle1, r2's the same for circle2)

Again, just yielding some ideas...


circles.png (26.0 kB)
Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Jamora · Oct 09, 2013 at 02:47 PM 2
Share

I missed your answer in the comments and posted my own, exactly the same answer (+1 for that BTW). A sure sign of an answer is if it has pictures...

avatar image verenion · Oct 09, 2013 at 03:00 PM 1
Share

I also would like to point out something...

If you're a circle, How can you tell if a point is inside you?

is the funniest thing I've ever read on UA

avatar image vexe · Oct 09, 2013 at 03:01 PM 2
Share

@Jamora man where did your answer go? :D

I wanted to say something about it, it works perfectly fine if all the circles had the same radius, but problems occur if we added smaller circles.

I don't think both the solutions circle around the same idea.

You mentioned something like (not literally): "If we had 2 circles c1, c2, assume point p belongs to the perimeter of c2. If dist(p, c1_center) < dist(p, c2_center) then we remove p"

Take a look at this:

alt text

In this situation, p belongs to c2, it should be removed, BUT dist(p, c1_center) > dist(p, c2_center) - According to your theory p is needed not to be removed.

j.png (6.6 kB)
avatar image Jamora · Oct 09, 2013 at 03:08 PM 2
Share

I deleted my answer because it's the same as yours and you posted yours first (as a comment, naughty).

You're right Vexe. What needed to be done is to compute the intersection points all mathematical-like, then determine which side should be removed. That would probably be even more performant than checking the distance of thousands of points. Easy, assuming they're ordered correctly in their list/array.

avatar image raimon.massanet · Oct 10, 2013 at 07:54 AM 1
Share

Oh, so the paths are perfect circles? I thought the paths were polygons...

Then the solution is much easier, as pointed out buy @Jamora and @vexe, because then you only need to calculate distance to centers.

You need to remove a point P if it DOES NOT belong to circle c1 but its distance to the center of c1 is smaller than the radius of c1.

You should do that for all points P and all circles different than the circle to which P belongs.

This has been suggested before by @Jamora, @vexe and @Bunny83, but I thought I would summarize.

Show more comments
avatar image
2

Answer by raimon.massanet · Oct 09, 2013 at 12:43 PM

I would delete the points in one path that are inside the area defined by the other path, and vice-versa. You can use ray casting for that:

http://en.wikipedia.org/wiki/Point_in_polygon

You should end up with the points that are in the boundary.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Oct 09, 2013 at 01:57 PM 1
Share

Since the shapes are circles it's easier to simply check the distance of a point from the other circle midpoint. If it's smaller the radius of the circle it's inside. In the end you have to find which "end" of one arc is connected to which other arc. It might be possible to save some hints during point elemination to make this task easier.

avatar image verenion · Oct 09, 2013 at 02:02 PM 0
Share

@Bunny83, Checking the radius has already crossed my mind, however, this wont work, as some of the circles could be smaller than others.

avatar image Bunny83 · Oct 09, 2013 at 03:01 PM 0
Share

@verenion: That's not a problem at all ;)

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

19 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Renderer on object disabled after level reload 1 Answer

Creating a LineRenderer: its always null 2 Answers

Making a bubble level (not a game but work tool) 1 Answer

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges