How to do arccontinue using a script?

Next
 From:  bemfarmer
10929.1 
Hi Michael,

Is it possible to do an Arccontinue arc, from the end of a line segment curve, to pointA, using a script?

Given:
TopView planar geometry, z=0.

1. lineBC segment from pointB to pointC, to which the Arccontinue is to be tangent. (lineBC is at 12 degrees from the vertical.)

2. PointB, which is the start point of the Arccontinue.
(The raw ptB is at ( 2, 1, 0 ).)

3. PointA, which is the end point of the Arccontinue.
(The raw ptA is at ( 1, 2, 0 ).)

4. The radius has a known value. (not needed.)

5. The center of the arc is unknown. (It could be calculated...)

Normally, Pointpicker is used to select pointB, and the tangent of the line segment is picked up by MoI, to complete the arccontinue arc.

Can Arccontinue be scripted?
Using lineBC.getStartPt() does not seem to pick up the tangent of lineBC. (???)

And what would be the correct type of point?
(ptB, ptObjB, or pointB (item(0)), or pointB.pt ???)

code:
	var ptA = moi.vectorMath.createPoint( 1, 2, 0 );
	var factory = moi.command.createFactory( 'point' );
	factory.setInput( 0, ptA );
	var ptObjA = factory.calculate();
	if ( !ptObjA )
		return false;
	var pointA = ptObjA.item(0);
	moi.geometryDatabase.addObject( pointA ); // Point A.

	var ptB = moi.vectorMath.createPoint( 2, 1, 0 );	
	var factory = moi.command.createFactory( 'point' );
	factory.setInput( 0, ptB );
	var ptObjB = factory.calculate();
	if ( !ptObjB )
		return false;
	var pointB = ptObjB.item(0);		
	moi.geometryDatabase.addObject( pointB ); // Point B.
	
	var ptC = moi.vectorMath.createPoint( 2.212557, 0, 0 );
	var factory = moi.command.createFactory( 'point' );
	factory.setInput( 0, ptC );
	var ptObjC = factory.calculate();
	if ( !ptObjC )
		return false;
	var pointC = ptObjC.item(0);		
	moi.geometryDatabase.addObject( pointC1 ); // Point C.	

	var linefactory = moi.command.createFactory( 'line' );
	linefactory.setInput( 0, pointB.pt );
	linefactory.setInput( 1, pointC.pt );	
	var lineobj = linefactory.calculate();
	if ( !lineobj || lineobj.length != 1 )
		return false;
	var lineBC = lineobj.item(0);
	moi.geometryDatabase.addObject( lineBC );

// The above 4 code sections are working well.

/*
// Various permutations of the following code do not work, so far:
//	var start = lineBC.getStartPt();	
//	var pointfactory = moi.command.createFactory( 'point' );
//	pointfactory.setInput( 0, start );
//	pointfactory.commit(); // should be point B	again.

	var startptObj = pointfactory.calculate();
	var startpointB = startptObj.item(0);		
	moi.geometryDatabase.addObject( startpointB );	


	// Create point object from curve end pt. (= C)
	// This is one input for Arc > Continue, arc to point D.		
	var pointfactory = moi.command.createFactory( 'point' );
	pointfactory.setInput( 0, lineBC.getEndPt() );
	var endpt = pointfactory.calculate();

	// Get startPt of lineBC, and also endPt.
	var startPt = lineBC.getStartPt();
	var endPt = lineBC.getEndPt();	
*/

	// Create arcAB, using arcontinue, from B to A.
	var arcfactory = moi.command.createFactory( 'arccontinue' );
//	arcfactory.setInput( 0, startpoint );
//	arcfactory.setInput( 1, pointA );	
//	arcfactory.setInput( 0, startpointObj );
//	arcfactory.setInput( 1, pointA );
	arcfactory.setInput( 0, startpointB.pt );
	arcfactory.setInput( 1, pointA.pt );	
	
	var arcObjAB = arcfactory.calculate();
	if ( !arcObjAB || arcObjAB.length != 1 )
		return false;
	var arcAB = arcObjAB.item(0);
	moi.geometryDatabase.addObject( arcAB );


Can pointpicker() be used, without picking a point?
Can the line tangent be obtained by script, and fed into arccontinue?

As a last resort, the Unknown CenterPt could be calculated, and then a 2point arc could be done.

Thankyou,
- Brian

The arccontinue, done manually with pointpicker(), ends up at 66 degrees.

EDITED: 25 Dec 2022 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
10929.2 In reply to 10929.1 
Hi Brian, the ArcContinue factory relies on the first point having an object snap set on it which can only be done by having the point supplied by a pointpicker.

re:
> And what would be the correct type of point?

It needs to be a "PickedPoint" object which is generated by the pointpicker and has additional data such as a list of object snaps.


> Can pointpicker() be used, without picking a point?

Sorry no it can't.


> Can the line tangent be obtained by script, and fed into arccontinue?

Unfortunately no, the arccontinue factory is only set up to get the tangent from an osnap on a picked point object.

So to do it in your script without using a picked point, the script would need to do the calculation itself.

There's a solution explained here:
https://www.emathzone.com/tutorials/geometry/equation-of-a-circle-given-two-points-and-tangent-line.html

or also here:
https://www.youtube.com/watch?v=nRAT0cyp74o

The way it's done in the arc continue factory goes like this:

Goal - calculate a circle given a point (PointA), the unit tangent of the circle at that point (TangentA) and a second point that the circle goes through (PointB).

First form a coordinate frame with the tangent as the x axis.

Get a vector between PointA and PointB as a second vector to cross with the unit tangent to get a plane normal.

Get a Y axis by crossing the normal with the xaxis.

Now the coordinate frame is formed with origin at PointA with xaxis being TangentA and the Y axis from the last step.

Get a 2D point B2D in the plane using B2D.x = frame.distancex( PointB ), B2D.y = frame.distancey( PointB ).

Then the calculation of the radius goes like this:

code:
	// The equation for a circle is (x - xcen) ^ 2 + (y - ycen) ^ 2 = radius ^ 2
	// The first circle point is at the origin, and the xaxis is tangent to the circle.
	// Since the xaxis is tangent, xcen = 0, and ycen = +/- radius.
	// Substituting in gives:
	//
	// x ^ 2 + (y - radius) ^ 2 = radius ^ 2
	//
	// Expanding, and moving the right side over to the left:
	// x ^ 2 + y ^ 2 - 2 * y * radius + radius ^ 2 - radius ^ 2 = 0
	//
	// The squared radius terms cancel out:
	// x ^ 2 + y ^ 2 - 2 * y * radius = 0
	//
	// Solving for radius:
	// 2 * y * radius = x ^ 2 + y ^ 2;
	// radius = (x ^ 2 + y ^ 2) / (2 * y)

	Radius = ((B2D.x * B2D.x) + (B2D.y * B2D.y)) / (2.0 * B2D.y);

	// The circle's origin is radius distance along the original frame's y axis.


- 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
10929.3 In reply to 10929.2 
Thankyou Michael!

It is good to know which direction to take. I am working on a script.

I was actually looking at your first link earlier this evening.

I'll study your solution, and incorporate it in my script.

So far I have had to correct several dozen of my programming errors, and am beginning to get a little better at using the several varieties of "points".
The reference paper so far has one +/- sign error, but may have another...Still a ways to go on deciphering the math...

- 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
10929.4 In reply to 10929.1 
Hi Michael,

After much study, I believe that I grasp your post and formulas :-), so I made a few notes.

(Note, swap Brian's point labels A and B, to conform to Michael's code. I believe that Michael's code, and arccontinue work in 3D. )

Notes on the code:
In the cplane Frame, for purposes of the computation of r or R, in order to find the center point of the arccontinue scripting, the value of R represents the y coordinate B2D.y, and so can be positive or negative. If R is negative, point A2D lies below the x-axis, and so A2D.y is negative. Or perhaps I should say, if point A2D lies below the x-axis, then R is negative. (Of course radii of circles are usually considered as being of positive distance.)
I had two quibbles with the last two sentences of the code.
The formula for the circle is essentially the pythagorean code.
Using R with its associated plus or minus value:
Forming a triangle for point A2D, gives the pythagorean formula:
((-1) * (R - B2D.y))^2 + (B2D.x)^2 = R^2. which is exactly the same
form as Michael derivation. So Michael's Radius =((B2d.x *...) applies. So keep the sign of R, to get the value of centerPt.y, and centerPt.x = 0, in cPlane Frame.

Convert centerPt back to world coordinates, and run arccenter with centerPt, pointA, and pointB, to get the script equivalent to pointpicker arccontinue command.

The last quibble is with the final sentence, which was confusing to myself. IMHO, drop the "original" text, and it should read something like:
The circle's origin is on the cPlane frame's y axis at point y = calculated R value, (maintaining the + or - value calculated.)

*************

It belatedly comes to mind that the script could calculate and create the line segment, and other points needed, and then ask the user to select the upper end of the line segment, with code using pointpicker.
Asking the user for the bottom end point, with code for a second pointpicker, would enable another arccontinue from point C to point D.

Can the pointpicker dialog be done in the "middle" of a script???,
after some geometry has been added to the geometry database?

(But I prefer the script to calculate the entire curve profile, without pointpicker interaction.)

- 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
 From:  Michael Gibson
10929.5 In reply to 10929.4 
Hi Brian,

re:
> Can the pointpicker dialog be done in the "middle" of a script???,
> after some geometry has been added to the geometry database?

Maybe I don't understand the question, but yes a pointpicker event loop can be executed at any location within a script.

- 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
 

Reply to All Reply to All