Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

path_extrude() behavior incorrect in latest release(s) but correct in v1.0.0 #5

Closed
chill1n opened this issue May 30, 2019 · 10 comments
Closed

Comments

@chill1n
Copy link
Contributor

chill1n commented May 30, 2019

Instead of a regular thread, I see a gradually rotated thread for increasing z.
With release v1.0.0 the behavior was correct, but with release v1.2.0 (and possibly older releases) the behavior is incorrect.
The code that shows this behavior is:

include <dotSCAD/rotate_p.scad>;
include <dotSCAD/polysections.scad>;
include <dotSCAD/path_extrude.scad>;

r = 10;
fa = 2;

shape_pts = [
// outer
[0,0],
[3, 1],
[0, 2]
];

path_pts = [
for(a = [0:fa:360 * 5])
[-r * cos(a), r * sin(a), a/100]
];

path_extrude(
shape_pts,
path_pts
);

The correct output result is shown below.

Screenshot at 2019-05-30 02-53-54

The incorrect output result is shown below.
Screenshot at 2019-05-30 02-57-31

@JustinSDK
Copy link
Owner

Actually, it's correct behavior of path_extrude in dotSCAD 1.1 or later because it takes different algorithm for rotating sections from path points.

If you want to extrude a shape along a path precisely, providing enough information about how to rotate sections is necessary. If you want to extrude a shape along a helix, helix_extrude is more suitable because it knows how to dig out necessary data for rotating sections precisely.

include <rotate_p.scad>;
include <polysections.scad>;
include <helix.scad>;
include <cross_sections.scad>;
include <helix_extrude.scad>;

r = 10;
fa = 2;

shape_pts = [
    [0,0],
    [-3, 1],
    [0, 2]
];


$fn = 360 / fa;

helix_extrude(
    shape_pts,
    radius = r,
    levels = 5,
    level_dist = 3.6,
    vt_dir = "SPI_UP"
);

helix1

If you have only points, what path_extrude can do is to guess data about rotations. The different algorithm will dig out different data. path_extrude in dotSCAD 1.0 just has the result you want but has an obvious bug in some situation. (See issue #3). The bug is fixed after v1.1.

If you still want to use path_extrude, one way to get what you want is using the twist parameter. For example:

include <rotate_p.scad>;
include <polysections.scad>;
include <path_extrude.scad>;

r = 10;
fa = 2;

shape_pts = [
    [0,0],
    [3, 1],
    [0, 2]
];

path_pts = [
    for(a = [0:fa:360 * 5])
    [-r * cos(a), r * sin(a), a/100]
];

path_extrude(
    shape_pts,
    path_pts,
    twist = 100 // adjust it
);

helix

In this situation, you provide information which path points do not provide. You think it's a bug in path_extrude after dotSCAD 1.1 because your brain has information that path points do not provide.

(Even though old algorithm of path_extrude has an obvious bug, it has some benefits in some situations. I'm still considering whether I should provide an option for users to switch these two algorithms in the later version.)

@JustinSDK
Copy link
Owner

JustinSDK commented May 31, 2019

I add a method parameter to path_extrude. It accepts two values, "AXIS_ANGLE" and "EULER_ANGLE".

include <rotate_p.scad>;
include <polysections.scad>;
include <path_extrude.scad>;

r = 10;
fa = 2;

shape_pts = [
    [0,0],
    [3, 1],
    [0, 2]
];

path_pts = [
    for(a = [0:fa:360 * 5])
    [-r * cos(a), r * sin(a), a/100]
];

path_extrude(
    shape_pts,
    path_pts,
    method = "AXIS_ANGLE"  // default
);

translate([r * 3, 0, 0]) path_extrude(
    shape_pts,
    path_pts,
    method = "EULER_ANGLE"
);

method

"AXIS_ANGLE" is the default value because "EULER_ANGLE" will generate an abrupt when the path is exactly vertical. It happened in (older) Blender, too.

"EULER_ANGLE", however, generates the same section at the same point. This means that you don't have to adjust sections if you want to extrude along a closed path. It's an advantage when extruding. For example:

include <shape_pentagram.scad>;
include <rotate_p.scad>;
include <polysections.scad>;
include <path_extrude.scad>;
include <torus_knot.scad>;

p = 2;
q = 3;
phi_step = 0.05;
star_radius = 0.5;

pts = torus_knot(p, q, phi_step);

shape_pentagram_pts = shape_pentagram(star_radius);

// not closed perfectly
translate([-8, 0, 0]) path_extrude(
    shape_pentagram_pts, 
    concat(pts, [pts[0]]), 
    closed = true,
    method = "AXIS_ANGLE"
);

// adjust it 
path_extrude(
    shape_pentagram_pts, 
    concat(pts, [pts[0]]), 
    closed = true,
    twist = 188,
    method = "AXIS_ANGLE"
);

// "EULER_ANGLE" is easy in this situation
translate([0, 8, 0]) path_extrude(
    shape_pentagram_pts, 
    concat(pts, [pts[0]]), 
    closed = true,
    method = "EULER_ANGLE"
);

method2

If no problem, the new parameter method will be documented in the next release.

@chill1n
Copy link
Contributor Author

chill1n commented May 31, 2019 via email

@JustinSDK
Copy link
Owner

JustinSDK commented May 31, 2019

"EULER_ANGLE" takes one vector between two points to dig out Euler angles required when rotating sections.

"AXIS_ANGLE" takes three points to determinate two vectors used for rotating sections. The sections are rotated by Quaternion. A simple figure is shown in issue 3 for explaining how it works.

"AXIS_ANGLE" is preferred because it doesn't generate an abrupt for most situations.

@chill1n
Copy link
Contributor Author

chill1n commented May 31, 2019 via email

@JustinSDK
Copy link
Owner

path_extrude is actually a workaround when you have/provide only path points.

If we have enough information (shape points, path points and angles basically), cross_sections can help us to generate sections. Once we have sections, polysections can help us.

@chill1n
Copy link
Contributor Author

chill1n commented May 31, 2019 via email

@JustinSDK
Copy link
Owner

JustinSDK commented Jun 1, 2019

Euler angle

euler

Axis angle

axis

If you still don't understand, I'll suggest you read the links I provided and read source code for details.

OpenSCAD-2019.05 was published just a few days ago so it's not urgent to leverage its new features in dotSCAD for compatibility.

For those annoy warnings when using OpenSCAD-2019.05 and dotSCAD 1.1/1.0, you may use dotSCAD 1.2. It's fixed.

The new version which works properly with OpenSCAD-2019.05 will be a target at dotSCAD 2.0. Please stay tuned.

@chill1n
Copy link
Contributor Author

chill1n commented Jun 2, 2019 via email

@JustinSDK
Copy link
Owner

JustinSDK commented Jun 2, 2019

If you really know what the problem is when using Euler angles and what the axis-angle rotation is. You'll know when "closing mismatch" happens.

If you really think it's simple to use the methods you list and easy to implement, you may try it by yourself. I currently have no idea about how to improve the situation.

Actually, what you mentioned in the label 1 have been done in path_extrude . This shows a fact that you didn't read through all code in path_extrude and figure out what it does.

As for the label 2, the same conclusion as I've said before.

If you want to extrude a shape along a path precisely, providing enough information about how to rotate sections is necessary.

I think your biggest problem is, why do you think generating the same section at the same point is the correct behavior?

dotSCAD is an opensource library. If you come out with a solution to solve the problem, just do it. Don't just say that something is easy or simple to implement.

@JustinSDK JustinSDK added the not a bug not a but label Jun 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants