Finding Tangents to a Curve
 1-20  21-40  41-60  61

Next
 From:  bemfarmer
11632.1 
Given a (scroll) curve which is made up, piecewise, of approximately semi-circular arcs:
Find the points on the curve which have horizontal (y), and vertical (z) tangents.
For the example curve, these 11 points are Apex and Nadir points, as well as Left-most and Right-most points.
Is there a script to do this? Or a suggestion for devising a script?
(Some sort of script would be helpful, but is not very important:-)

The midpoint of a chord of the arc, extended to intersect the curve at a point, can approximate the tangent point, and can be a candidate point.

The Tan snaps and the y-axis and z-axis snaps can be used to find the 11 points, by trial and error, by drawing a line segment from an estimated tangent point,
and observing the MoI snap flags near the candidate point, as the line segment is rotated slightly during formation, and the corresponding angle(s) of the line segment when it Snap Flags as Tan.

For example, to find the Apex point at the top of an arch shaped section of the scroll curve, find an estimated candidate point, and draw a line segment from that point, to the left.
When the Tan snap flag appears near the point, if the left end of the line segment is below the horizontal flag indicator (y), the the actual apex tangent point lies Clockwise.
Repeat with new candidate point. The actual apex point can be bracketed on each side, by Clockwise or Counterclockwise corrections. By numerous trial and error, the point which simultaneously displays Tan and y flag, is the Apex point.

The procedure to find Nadir points (horizontal tangent) and Left and Right points with vertical tangents, is similar.

In the attached scroll curve, 4 apex points have already been locate by trial and error, within the tolerance of the MoI Tan and Y flags.


- Brian

I think that two bracket points could be found manually, and entered into a script.
The script would find a point on the curve, midway, arc-length-wise, between the two points.
Perform tangent slope value using existing properties of points on the curve, (MoI version 4 methods), and zero in on the "apex" point. (tangent slope value zero...)
Repeat with the "mid-point", determine CW or CCW, and repeat using the appropriate one of the two bracket points. Such algorithms exist...

EDITED: 17 Jan by BEMFARMER


  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  bemfarmer
11632.2 In reply to 11632.1 
It might be a Quadrant snap, or a Quadrant point?
Or some sort of bounding box?
Bounding box command works if the curve is cut up appropriately.


- B

EDITED: 17 Jan by BEMFARMER

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
11632.3 In reply to 11632.1 
Hi Brian, try this (requires v5):

code:
function GetTangents( crv, dir )
{
    var params = crv.getTangentsToDir( dir );
    for ( var i = 0; i < params.length; ++i )
    {
	var pt = crv.evaluatePoint( params.item(i) );
	var factory = moi.command.createFactory( 'point' );
	factory.setInput( 0, pt );
	factory.commit();
    }
}

GetTangents( moi.geometryDatabase.getObjects().getCurves().item(0), moi.vectorMath.createPoint(0,0,1) );
GetTangents( moi.geometryDatabase.getObjects().getCurves().item(0), moi.vectorMath.createPoint(0,1,0) );


- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Larry Fahnoe (FAHNOE)
11632.4 In reply to 11632.3 
Hi Brian & Michael,

Good timing on this Q&A as I'm noodling on something & this approach may end up being very helpful. Thanks to you both!

--Larry
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  bemfarmer
11632.5 In reply to 11632.3 
Thank you Michael

WOW!
The script works perfect on the sample scroll curve.

(Limited planar YZ testing.)
The script will work from command line, or as a shortcut key, if there is only one curve in the 3dm.
If there are two curves, only one curve receives tangent points. Which one seems to be related to which of the two curves is "Active."
Selecting the curve does not change the "Active" curve.
Deleting the points, and re-running the script just creates the tangent points on the same curve.
It is possible to get the "Active" curve to switch to the other curve, by deleting the active curve.

Starting from a blank screen geometry:
Draw a line. The script does not produce any points (Good).
Add a circle. The script does not produce any points, because the line is at the top of the "curve list". (OK)
(I do not know what the "curve list" is.)

Erase all of the curve geometry, and draw a circle, then a line. The script works perfect on the circle. (Good)

Erase all of the curve geometry, and draw a big circle and a small circle. The big circle is at the top of the "curve list", and the script finds the 4 tangent points for Y and Z direction. (Good).
Picking the small circle does NOT bring it to the top of the "curve list".

So maybe add some "pick curve" dialog, and somehow place the curve at the top of the "curve list".???

- Brian

Having other existing points does not seem to have any detrimental effect.
Having a hidden image does not seem to hurt either.
Hiding the "active" curve (circle) does NOT reduce its "active" status. The script will still find the same tangent points.

Will try some more curves, 3d and other planes...

- Brian

I assume that tolerance reduces the number of candidate tangent points to less than "infinity.":-)
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  bemfarmer
11632.6 In reply to 11632.3 
I added a third GetTangents line with (1,0,0)

With the (2d) LogSpiral script run, in either Top, Front, or Right view, the modified GetTangents script finds the Horizontal and Vertical tangent points.

(A curiosity, the LogSpiral just needs to be created by the LogSpiral script. The LogSpiral script does not have to be completely closed (Done +Done), but can be finished (Done + Done).)

- Brian
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  bemfarmer
11632.7 In reply to 11632.6 
The GetTangents script works on many tested 2d curves.
Curves like the helix did not have any such tangents.

Curves with line segments???

The script does not like sphere, cone, cylinder, box.

The script does not like blank screen. (No geometry)

- Brian

EDITED: 20 Jan by BEMFARMER

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
11632.8 In reply to 11632.5 
Hi Brian,

re:
> So maybe add some "pick curve" dialog, and somehow place the curve at the top of the "curve list".???

Yes that wasn't really meant to be a finished tool, it was just some example script code for calling crv.getTangentsToDir() so you could use it in your own script you're working on.

Here's an adjusted version that will work on selected curves:

code:

function GetTangents( crv, dir )
{
    var params = crv.getTangentsToDir( dir );
    for ( var i = 0; i < params.length; ++i )
    {
	var pt = crv.evaluatePoint( params.item(i) );
	var factory = moi.command.createFactory( 'point' );
	factory.setInput( 0, pt );
	factory.commit();
    }
}

var curves = moi.geometryDatabase.getSelectedObjects().getCurves();
for ( var i = 0; i < curves.length; ++i )
{
	var crv = curves.item(i);
	GetTangents( crv, moi.vectorMath.createPoint(1,0,0) );
	GetTangents( crv, moi.vectorMath.createPoint(0,1,0) );
	GetTangents( crv, moi.vectorMath.createPoint(0,0,1) );
}



re:
> Curves like the helix did not have any such tangents.

Yes a helix is a 3D curve it doesn't have any spots on it that are tangent to the world x/y/z axis directions. The tangent of a helix will have some component of the helix axis direction in it.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Larry Fahnoe (FAHNOE)
11632.9 In reply to 11632.4 
Forgive a mini-hijack of the thread please, but Michael's code fragment prompts a related question.

I am seeking to write a script to simulate bending metal barstock based on the method described in the attached file. The first step of the method is to find the red lines tangent to two curves, but I'm not thinking that getTangentsToDir() is going to help me find such. Am I wrong, or are there any other tangent methods that might help? I reviewed the V4 and V5 beta notes but didn't find anything promising.

--Larry
Attachments:

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  bemfarmer
11632.10 In reply to 11632.8 
Hi Michael,

Thank you again for this terrific script.

I've assigned it a hotkey.

It may be included in a future program.

- Brian
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
11632.11 In reply to 11632.9 
Hi Larry, there is curve.getTangentsToDir( dir ) and curve.getTangentsToPoint( pt ) but neither of them will calculate tangents between 2 curves.

Are your 2 curves always circles or circular arcs like in your .3dm file?

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  bemfarmer
11632.12 In reply to 11632.9 
Hi Larry

I vaguely recollect this Tangent lines to two circles from a few years ago.

https://en.wikipedia.org/wiki/Homothetic_center

https://en.wikipedia.org/wiki/Tangent_lines_to_circles

Still researching...

- Brian

There is a MoI tan/tan tan/tan snap, if the start and end points are in the vicinity (by eye) of the tan points..

EDITED: 17 Jan by BEMFARMER

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  bemfarmer
11632.13 
So calculate the inner homothetic point, (x0,y0), and then use curve.getTangentsToPoint( pt ) (???)

Sounds relatively do-able.

- Brian
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  bemfarmer
11632.14 In reply to 11632.13 
Some partial code, untested:

// z plays the roll of y in xz plane.
// or use circle1 and circle 2, and extract circle1.x circle1.z, etc.
function GetInnerHomotheticPt( radius1, x1, z1, radius2, x2, z2 )
{
var y0 = 0.0;
var radiusSum = radius1 + radius2;
var ratio1 = radius1/radiusSum;
var ratio2 = radius2/radiusSum;
var x0 = ratio2 * x1 + ratio1 * x2;
var z0 = ratio2 * z1 + ratio1 * z2;
return moi.vectorMath.createPoint( x0, y0, z0 );
}

// select left circle (roller) and die circle, and get centerPt1 and radius1 and centerPt2 and radius2... and centerPt1.x1, centerPt1.z1, etc.
// or pass centerPt1 and centerPt2 and extract .x1 etc in function called.
// Also need to do same thing for right hand circle (roller), as there will be TWO InnerHomothetic points.

var ptInner1 = GetInnerHomotheticPt( radius1, x1, z1, radius2, x2, z2 );
var factory = moi.command.createFactory( 'point' );
factory.setInput( 0, ptInner1 );
factory.commit();
// Repeat for ptInner2.
****
// Now use ptInner1 with curve.getTangentsToPoint( ptInner1 )to find
// tangent point of left circle (roller), and also for die (semi)circle.
// Repeat with ptInner2 for right circle, and also for die (semi)circle.

- B
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Larry Fahnoe (FAHNOE)
11632.15 In reply to 11632.11 
Hi Michael,

> Are your 2 curves always circles or circular arcs like in your .3dm file?

Yes, the circular arcs will be the most common sort of die to simulate.

Hi Brian,

Thank you for your references & code, I shall read and tinker further!

--Larry
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
11632.16 In reply to 11632.15 
Hi Larry,

re:
> Yes, the circular arcs will be the most common sort of die to simulate.

The case of tangent between 2 circles can be solved directly.

A really good source for this kind of thing is the book "A Programmer's Geometry", which can be accessed on archive.org here:
https://archive.org/details/AProgrammersGeometry

See section 2.6 "Tangents between 2 circles".

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  bemfarmer
11632.17 
I spent some time working on tangents to two disjoint circles, and reviewing lots of forum posts, and several existing scripts.

Larry's code here:

https://moi3d.com/forum/index.php?webtag=MOI&msg=9916.22

provides short and simple code to select the "Roller" circle, arc Die circular arc, and the second "Roller" circle, in all views.

The center points are created. var cpoint = curves.item( i).conicFrame.origin;

I am wondering if cpoint.x, and cpoint.y, and curves.item(i).radius will yield the (x,y,0) coordinates, and the radius of each circle???
(In MoI5 beta???)

Or is some GetRadius, or evaluate... needed?

Or is var x = cp.distancex( cpoint).toFixed( digits);
var y = cp.distancey( cpoint).toFixed( digits);
var z = cp.distancez( cpoint).toFixed( digits);
needed??? (MoI4???)
And can the .toFixed(digits) be omitted???

It seems like cpoint is a "raw" point, not a Geometry point???
pointfactory can turn cpoint into a Geometry point.


- Brian

EDITED: 18 Jan by BEMFARMER

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  bemfarmer
11632.18 In reply to 11632.16 
Too much Fortran for me:-)

I think r + ve means radius with a positive value. (ve meaning value???)
On second thought, I think that r + ve, means use the positive version of radius. (ve meaning version)

Looking at the ax + by +c = 0 equation,

a = (-/+ radiusL +/- radiusK) * (xL - xK) - ...

where xL means the x coordinate of the center point L of circle L.
rL means the radius of circle L.

The inner and outer tangent line equations are calculated using the 4 combinations of +/- radiusL and +/- radiusK
So the math is not as abstruse as I initially thought.

How to convert ax + by + c = 0 into a MoI line segment???

- Brian

AI conclusions may or may not be faulty, but:

AI Overview
Learn more
To plot a line from the equation "ax + by + c = 0," you need to first rearrange the equation to solve for y (to get it in slope-intercept form, "y = mx + b"), then find the y-intercept (b) and the slope (m), and use those values to plot the line on a graph by finding two points on the line and connecting them; you can also find the x and y intercepts directly by plugging in 0 for y and x respectively and solving for the other variable.

EDITED: 18 Jan by BEMFARMER

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
11632.19 In reply to 11632.17 
Hi Brian,

re:
> The center points are created. var cpoint = curves.item( i).conicFrame.origin;
>
> I am wondering if cpoint.x, and cpoint.y, and curves.item(i).radius will yield the (x,y,0) coordinates, and the radius of each circle???
> (In MoI5 beta???)

cpoint.x and cpoint.y will have the x,y coordinates of the circle's center point, and curves.item(i).conicRadius will have the radius value.


> Or is var x = cp.distancex( cpoint).toFixed( digits);

.toFixed() is for converting a numeric value into a string value.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  bemfarmer
11632.20 In reply to 11632.19 
Thank you very much Michael.

I reviewed the 1983 geometry book, and adjusted previous post :-)

- Brian
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged
 

Reply to All Reply to All

 

 
Show messages:  1-20  21-40  41-60  61