Subtracting shapes - 2

You may recall this thread I made a couple of weeks ago:

I specifically want to do this in Python.

I’ve tried my method, @jacob.small and @c.poupin methods from the thread.

All work beautifully… However.

After subtraction the order of the lines does not flow.

See image for better explanation

Has anyone got any suggestions how to overcome this?

Yes, I could convert to surface maybe… but I’d rather avoid this if possible.

EDIT: Bob my assistant :baby_chick: thinks maybe if I force both sets of lines to run anti-clockwise (or both clockwise) it may solve this issue… I will try that tomorrow… But if you’ve got any other suggestions please let me know!

Simplest method? PolyCurve.ByGroupedCurves.

However if you’re concerned with the order my instinct tells me you’re doing more than subtracting lines… what is the start point and end goal? If they are what I think then you might be better off approaching the problem differently.

I’m placing items in an area.

But I don’t want the items to clash.

I’m experimenting with different ways of doing this (partially for fun, partially because I think it could be useful for other stuff).

3D or 2D?
Clearances or just solids?

Either way, lines are not sufficient.

:slight_smile:

2D. Why are lines not sufficient?

Say you have a space that is 10x10. And say you have three objects that are 1x1, 2x2, and 3x3.

If you put all of them at the center of the space there is no clash between the elements’s curves, but the things certainly cannot be on top of each other.

You’d retain all the lines… So there’d be no issue.

What sort of object consists of just lines on the perimeter though?

You’ve lost me.

Let’s say, for argument sake (we can make it more complex later) that we have a 2d shape and subract another 2d shape that definitely overlaps.

How to keep the lines in the order that goes round the shape.

Is it a 2D shape as in a surface like you have with an abstract representation of say a table and chair, or a 1D shape as in a curve (meaning it has no depth along it’s path and doesn’t branch)?

If 1ad explain to me what problem we are actually solving here as I cannot think of a real life example of a 1D shape.

If 2D I would use surfaces, so Surface.Difference, as I cannot put the chair inside the table without moving into 3D shapes at which point I would use solids…

I already did it with surfaces…

I want to do it with lines :smiley:

It’s a 2d closed polygon minus a rectangle where at least one of the rectangle’s lines totally overlaps the original 2d closed polygon.

As in our original codes… The code will subtract (see the picture in the first post on here) and give me the new polygon.

However, I want the polygon’s lines to be one after another in order, as you’d draw it with a continuous line if you had a pen on paper.

The first image, I want to ensure the new polygon (the one on the right) has lines 0 - 5 in order… You can see that currently in the example it goes 0, 1, 2, 3, 5, 4.

PolyCurve.ByGroupedCurves followed by exploding each polycurve will do that trick…and far faster than any list management complications you’d get from trying to join things sequentially.

Hopefully this gives you some direction as I don’t understand what you’re actually after at the conceptual level.

1 Like

Sometimes things are just interesting…

I’m trying to subtract a rectangle from a polygon.
Then trying to subtract another rectangle from the resultant polygon (after checking the second rectangle is within the polygon)

I’ve done it using surfaces. I did it using points in polygons (points for the rectangle, lines for the polygon). I did it with points in polygons (points vs points) Now I’m trying with lines for the polygon and lines for the rectangle.

I do find if you’re playing with lots of surfaces in Dynamo it’s really slow… So I’m interested in other methods. I like messing about with stuff.

I really do want to subtract rectangles from polygons in different ways :smiley:

I reckon the anti-clockwise method may work…
Otherwise maybe I try starting with a line and getting endpoint and finding which line’s startpoint is at the endpoint.

Making sure the curves ran anti-clockwise didn’t help.

I resorted to getting start-end points and putting those in order.

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

boundary_lines = IN[0]  # List of lines

ordered_lines = []

# Start with the first line
current_line = boundary_lines[0]
ordered_lines.append(current_line)

# Remove the first line from the boundary_lines list
boundary_lines.pop(0)

# Function to check if two points are equal
def points_are_equal(point1, point2):
    return point1.X == point2.X and point1.Y == point2.Y and point1.Z == point2.Z

while boundary_lines:
    current_end_point = current_line.EndPoint
    
    for line in boundary_lines:
        if points_are_equal(line.StartPoint, current_end_point):
            current_line = line
            ordered_lines.append(line)
            boundary_lines.remove(line)
            break
        elif points_are_equal(line.EndPoint, current_end_point):
            current_line = Line.ByStartPointEndPoint(line.EndPoint, line.StartPoint)  # Reverse the line
            ordered_lines.append(current_line)
            boundary_lines.remove(line)
            break
    else:
        # If no matching point is found, break the loop
        break

OUT = ordered_lines

It’s not even 10am here and I’ve already had one infinite loop… Soooo wish there was a break function :stuck_out_tongue_closed_eyes:

Stop writing open loops then.

Try this: sortedCurves = [ i.Curves for I in PolyCurve.ByGroupedCurves(trimmedCurves) ] which should make the issue go away.

1 Like

6ms is the margin of error… you have a zero time function right there. :smiley:

In Python, calling one C# function to complete a loop will almost always outperform a custom loop that calls many C# functions in it.

1 Like