Ruby Help : intersect to curves and remove trailing

I have two curves built from two equations. How do I find the intersect point AND delete the two remaining pieces of curve? The removed pieces would be the last points in each of the arrays.

line1 = curve1()
line2 = curve2()
#they are known to intersect.

line3 = combineLines line1, line2

def combineLines(l1, l2)
…?
end

Show an image of what you have, and what you’d like to trim.

So I have these two curves that will eventually be made into an extruded profile, but I need to connect the two lines (easy) but first calc the intersection point, truncate the line at that point and append the point and second line

Clipboard02

This would easier if you use the latest version (2020.1,) as it added Entities#weld to combine curve objects.

There are likely some older work around code snippets either here or at SketchUcation.
Search on the term “weld”.

As a general workaround, you might iterate the edges array of each curve, getting the segment’s representative line and test whether it intersects one of the other curve’s edge’s lines.

See: Geom::intersect_line_line()

This will give you the intersecting point.

You could then move one of each curve’s vertices to that point (if there is not already a vertex there.)


Note that if one of the curves is an ArcCurve, it simplifies the finding of the intersecting point, as you can get a plane directly from an ArcCurve, and use the Geom::intersect_line_plane() module method.

If the curve is not an actual arc, but you know it is planar, then you can get it’s plane by using the Geom::fit_plane_to_points() module method.

plane1 = Geom::fit_plane_to_points(curve1.vertices.map(&:position))
edge = curve2.edges.find {|edge| Geom::intersect_line_plane(edge.line,plane1) }
if edge # nil if no intersect was found
  intersect_point = Geom::intersect_line_plane(edge.line,plane1)
else
  # recover gracefully
end

With regard to moving vertices, … since they are not Drawingelement subclasses, you cannot directly erase them, or apply a transformation as you would for a group or component instance.

Instead you must use one of the batch transform methods …

If you move several of the trailing vertices in a curve to a coincident point, SketchUp should merge them, and the effect would be a trim. :crossed_fingers:

There must be a matching number of point arguments in the move or transform method call to the vertices in the curve, … otherwise you are likely to get an ArgumentError.

The curves are not arcs as they are lines from angular equations{involute,trochoidal}. (I haven’t been able to solve the two equations to find and intersection)

First problem is that intersect_line_plane is that the plane and line are coplanar .
Second intersect_line_line() intersects lines not line segments. So all my lines actually intersect as they are in the same plane.

So then you have to check bounding conditions for each point. But that just finds the point. Then I have to split the two curves on that point and discard the remaining parts.

Ended up being easier to iterate over the raw array using linear algebra equation for line intersection and removing remaing values, then creating the curves for the data.
Was hoping for built in method to do this simple type of function but so far, no luck.

	def intersect(p, p2, q, q2)
	a = p2.y - p.y
	b = p.x - p2.x
	c = a*p.x + b*p.y

	a1 = q2.y - q.y
	b1 = q.x - q2.x
	c1 = a1*q.x + b1*q.y

	det = a*b1 -a1*b

	if det == 0 
		return
	else 
		x = (b1*c - b*c1)/det
		y = (a*c1 - a1*c)/det

		if [p.x,p2.x].min <= x && [p.x,p2.x].max >= x && [p.y,p2.y].min <= y && [p.y,p2.y].max >= y &&
			[q.x,q2.x].min <= x && [q.x,q2.x].max >= x && [q.y,q2.y].min <= y && [q.y,q2.y].max >= y
			return [x,y,0]
		end
	end
end

def intersectLines(l1, l2)
	cnt = 0
	## intersection will be at the end
	(l1.size-1).downto 1 do |i|
		p = l1[i]
		p2 = l1[i-1]
		#intersection will be at the front
		1.upto l2.size-2 do |j|		
			q = l2[j]
			q2 = l2[j+1]

			int = intersect(p,p2,q,q2)
			if !int.nil?
				l2.shift(j+1)
				l1.pop(cnt+1)
				l1.push int
				nl = l1+l2
				return nl
			end
		end
		cnt = cnt +1
	end
end
1 Like