API redefinition required!
-
the specific redefinition pertains to current code for ArcCurve.end_angle, the current code is documented below:
# Create a 1/2 circle, normal to the Z axis center = Geom;;Point3d.new normal = Geom;;Vector3d.new 0,0,1 xaxis = Geom;;Vector3d.new 1,0,0 start_a = 0.0 end_a = Math;;PI model = Sketchup.active_model entities = model.entities edgearray = entities.add_arc center, xaxis, normal, 5, start_a, end_a edge = edgearray[0] arccurve = edge.curve end_angle = arccurve.end_angle
the code for ArcCurve.end_angle: is sadly missing 3D co-ordinate input for start_a.
A radian circle provides adequate information about the arc: ie 30 degree= PI/6 etc.
http://math.rice.edu/~pcmi/sphere/drg_txt.html
What I'm interested in is making sure the arc starts at a pre-defined 3D-coordinate.
If I can find the center of the arc, I can also quickly find the starting co-ordinate for the arc,
which would make the current value for start_a redundant.The attached pic. shows the problem that occurs with the current definition of start_a
Hence if start_a were rewritten to reflect the properties of a 3d point, the arc would show correctly in the other 2 views of my wall section ruby. see attached pic below
I can't foresee if under a new redefinition a value for end_a would be required at all.
(for none architect types, the arc's and lines between the wall represent batt insulation)
-
ArcCurve.start_angle and ArcCurve.end_angle
The .start_angle and .end_angle methods retrieve the angle of the start/end of the arc, measured from the x-axis in radians.
The ArcCurve.xaxis gives that arc's local x-axis.
Whilst .normal and .center give further info.
I fail to understand your issues ?
The .start_angle is readily found from the arc's center/normal/xaxis...
This determines the point it will start at; just as the .end_angle determines the point it will end at. The points if are effectively the center-point offset by the radius along the local x-axis and then transform-rotated about the center-point using the arc.normal as the axis.
An arbitrary point you gave might not even be on the arc's plane, or if it were but then not the radius away from the center etc it will fail.
So if you know the required start point then you can work in the other direction and offset it in a plane to give the center, the start_angle is then simply that between the radius vector from the center to the point and the local x-axis ??
Examine my 2dTools Fillet script which has to work out 3d points where the arc fillet could start/end, it's center, normal etc and then construct the arc to suit these two points, trimming/extending the two edges as needed.It would be quite possible for you to make a new arc creating tool adding an arc between two points of a set radius and normal; the center taking care of itself etc... BUT you still need to do the calculations to get this... See 2dTools 2pt Arc which does this with normal=Z_AXIS, pick two points enter the radius, or 3pt where the third point sets that too... you just need to amend these to the general case for any other 'normal' vector...
-
@tig said:
I fail to understand your issues ?
You obviously did not take a closer look at the attached picture. The user can draw a wall at any angle, the ruby correctly identifies and draws a wall section at any angle the user chooses. The 3 arc's I'm talking about work only for a static locations not a user oriented locations. Hence the arc's, while containing the correct center, do not respond to a change in the orientation of the wall as shown in the other 2 wall samples, in the picture.
Hence in my opinion, a more practical solution would have been to make start_a a 3d point. -
They cannot change the method now. Too many plugins would break.
Perhaps they could allow that argument to be variable, angle orPoint3d
, but don't hold your breath. There are too many other things to fix in the API, and missing features.You best solution.. is to write a wrapper method in your OWN namespace, that will take a
Point3d
for that arg, do internal calculations, and call the standard method.def Tomot;;Lib.add_arc( entities, centerpoint, vectorX, vectorN, length, start_pt, end_pt ) # do calcs entities.add_arc(entities, centerpoint, vectorX, vectorN, length, start_a, end_a) end #def
-
tomot
You clearly do not understand what I said.
The arguments for
entities.add_arc
are
center=A Point3d object representing the center.
xaxis=A Vector3d object representing xaxis for the arc.
normal=A Vector3d object representing normal for the arc.
radius=The radius of the arc.
start_angle=Start angle for the arc.
end_angle=End angle for the arc.
num_segments=(optional)How many segments to draw.You are setting axes bases on the model axes and then trying to use these to draw on non-flat face.
This is bound to fail as the specified axes are not those needed when drawing the arc at this orientation.***It's NOT
entities.add_arc center, xaxis, normal, 5, start_a, end_a
IT'S better as
entities.add_arc(center, xaxis, normal, 5, start_a, end_a, 12)
This always makes a 'flat' arc if the normal==Z_AXIS
If you set it to be say a face-normal the arc will be drawn on the face.
IF you want the arc to start at a certain point on the face [you ought to check that the point is on the face or be sure it is in other ways like using the positions of face vertices] then simply set your xaxis to be a vector from the 'center' to the 'magic_point'
xaxis=center.vector_to(magic_point)
IF you are adding the arc to a rotated face get the xaxis from its two short edge vertices, or usexaxis=X_AXIS.transform(Geom::Transformation.rotation(ORIGIN,normal, fangle))
- where 'fangle' is the known rotation of the face - e.g. you already have decided to draw this form angled so know what 'fangle' is... or useface.edges[0].line[1].angle_between(X_AXIS)
You are already [unnecessarily] setting xaxis=X_AXIS so it's not even an extra line of code. Then the arc will 'start' at the 'magic_point' - that's assuming 'magic_point' is 'radius' away from the 'center' - or otherwise the center/start/magic_point will all in the same 'line'; and it sweeps through 180 degrees, drawn on the plane of a face whose normal you have used as the arc's normal OR 'flat' if you used Z_AXIS.If you want to set the xaxis of a face that you know to be vertical [as in your 'wall section tool'] then you simply use a 'cross' of the Z_AXIS and face's normal thus
xaxis=face.normal.cross(Z_AXIS)
.You do not need to reinvent the wheel - it's easy enough to set the xaxis of any curve
A few other 'gripes'... while I'm at it!
***Parenthesize your argumentsdothis(1, 2)
NOTdothis 1, 2
.
Use '180.degrees' rather than convoluted the 'Math::PI' stuff - as it's much easier to understand on rereading it.
Don't add objects directly into themodel.entities
unless that's really [rarely] where you want it to go; rather usemodel.active_entities
- this might be the model entities but if the user is editing a group when the tool is activated it uses the group's entities; it's often better to add a group to the active entities, then add objects to that groups entities, it makes keeping track of stuff much easier and does not interfere with preexisting geometry - you can always explode the group at the end so its contents merge with the other geometry if that's what you want. -
@dan rathbun said:
They cannot change the method now. Too many plugins would break.
You are right! and that's why a lot of software eventually becomes bloatware, In order for everything to work from day one, the only solution is to keep adding on, and filling in gaps in the API.
And then there is my friend TIG,.....who would like to convince me otherwise, and who's dedication to this forum should not be overlooked. Thanks for your lengthy reply TIG.
-
I finally got it a few days ago! I think I finally understand TIG's long informative explanation
#...required if arcs are going to rotate correctly within the rotating wall rectangle
$vecx = $pt22 - $pt11
$vecy = $pt11 - $pt1#...1.draw the 180 degree insulation arc center = Geom::Point3d.new $pt550 start_a = 0.0 end_a = Math::PI edgearray = entities.add_arc center, %(#FF0000)[$vecx], $normal, 1, start_a, end_a edge = edgearray[0] arccurve = edge.curve end_angle = arccurve.end_angle
-
Tomot
Please don't use global
$
variables unless you really have to@
ones are limited to your module/class - the$
ones are seen by all tools and a common name like$vecx
might have been used in another script [again ill-advisedly] and thereby either your or the the other script might not work as expected...
Alsoend_a=Math::PI
could easily becomeend_a=180.degrees
and be much easier to understand...I think you have the Arc basics now
-
@tig said:
Please don't use global
$
variables unless you really have toRats! I can't count how many times I have been reminded of that issue.
My typical response: I use global's so I can verify the 3d point location in the Ruby console, I need this to verify any mistakes I may be making (which happens frequently !) when I'm developing a script which corresponds to 3d points on my gridded 1/4" notepad. It would be really nice if @ variables where able to display the same information in the Ruby console.
Advertisement