JustinSDK / dotSCAD

Reduce the burden of mathematics when playing OpenSCAD
https://openhome.cc/zh-tw/openscad/
GNU Lesser General Public License v3.0
784 stars 107 forks source link

path_extrude() artifacts when path touches Z axis #3

Closed lorf closed 5 years ago

lorf commented 6 years ago

When path_extrude() given a path that touches axis parallel to Z, it produces some artifacts in the touch area. Code to reproduce:

include <../src/rotate_p.scad>;
include <../src/bezier_curve.scad>;
include <../src/polysections.scad>;
include <../src/path_extrude.scad>;

shape_pts = [[5, -5], [5, 5], [-5, 5], [-5, -5]]; // 10mm square

// Path produced with bezier_curve():
//curve_pts = [[20,20,0],[10,10,10],[20,20,20]];
//path_pts = bezier_curve(0.1,curve_pts);
path_pts = [[20, 20, 0], [18.2, 18.2, 2], [16.8, 16.8, 4], [15.8, 15.8, 6], [15.2, 15.2, 8], [15, 15, 10], [15.2, 15.2, 12], [15.8, 15.8, 14], [16.8, 16.8, 16], [18.2, 18.2, 18], [20, 20, 20]];

path_extrude(shape_pts,path_pts,triangles="SOLID");

Result: image

The workaround is to rotate the path so that it doesn't touch Z:

include <../src/rotate_p.scad>;
include <../src/bezier_curve.scad>;
include <../src/polysections.scad>;
include <../src/path_extrude.scad>;

shape_pts = [[5, -5], [5, 5], [-5, 5], [-5, -5]]; // 10mm square

// Path produced with bezier_curve():
//curve_pts = [[20,20,0],[10,10,10],[20,20,20]];
//path_pts = bezier_curve(0.1,curve_pts);
path_pts = [[20, 20, 0], [18.2, 18.2, 2], [16.8, 16.8, 4], [15.8, 15.8, 6], [15.2, 15.2, 8], [15, 15, 10], [15.2, 15.2, 12], [15.8, 15.8, 14], [16.8, 16.8, 16], [18.2, 18.2, 18], [20, 20, 20]];

path_pts_tmp = [ for(p=path_pts) rotate_p(rotate_p(p, [0,0,45]),[0,90,0]) ];
rotate([0,-90,-45])
    path_extrude(shape_pts,path_pts_tmp,triangles="SOLID");

image

JustinSDK commented 6 years ago

The problem comes from the section function within the path_extrude module because it rotates each point of a section around Z first. When path touches Z axis and its projection on the XY plane makes a (nearly) 180-degree turn, the problem happens.

Currently, avoiding such a path or the workaround you provided are ways to keep the problem away.

I am trying to figure out a solution to solve it.

TLC123 commented 6 years ago

You're looking for "frenet frame rotation" or similar solutions

On Wed, 2 May 2018, 10:16 Justin Lin, notifications@github.com wrote:

The problem comes from the section function within path_extrude because it rotates each point of a section around Z first. When path touches Z axis and its projection on the XY plane makes a (nearly) 180-degree turn, the problem happens.

Currently, avoiding such a path or the workaround you provided are ways to keep the problem away.

I am trying to figure out a solution to solve it.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/JustinSDK/dotSCAD/issues/3#issuecomment-385899771, or mute the thread https://github.com/notifications/unsubscribe-auth/AKcAab-NfriCqd4ctT6NlbX-AgfY_n2Hks5tuWt4gaJpZM4TtkGY .

JustinSDK commented 6 years ago

As far as I know, the problem of using only points to describe a path is that we don't have enough information about the path, such as how to rotate our cross-sections. The path_extrude module itself is actually a workaround for a path without a curve equation. The Frenet–Serret formulas seem not helpful here.

If we have a curve equation such as Archimedean spiral, cross_sections is more suitable.

If we only have the points of a path and path_extrude cannot create the model we want, try paths2section as an alternative which uses more paths to create the model we want.

I'm studying the Frenet–Serret formulas. Maybe one day, I can come up with a frenet–serret_extrude module for the occasion we have the curve equation r(t).

PaulF8080 commented 5 years ago

I you split it into two extrusions, you can see the two faces/sections crossing each other. Not a bug in my opinion. path_ptsa = [[20, 20, 0], [18.2, 18.2, 2], [16.8, 16.8, 4], [15.8, 15.8, 6], [15.2, 15.2, 8], [15, 15, 10]]; path_extrude(shape_pts,path_ptsa,triangles="SOLID");

path_ptsb = [[15.2, 15.2, 12], [15.8, 15.8, 14], [16.8, 16.8, 16], [18.2, 18.2, 18], [20, 20, 20]]; path_extrude(shape_pts,path_ptsb,triangles="SOLID"); `

test
PaulF8080 commented 5 years ago

I was thinking that if it was a crossed section problem, a smaller shape would fix it. No. Crossed isn't the problem. No overlap revealed a twist. So I echoed the points sent to the polyhedron and pasted the points as pts in this code I added. module test_polysections_solid(points, faces) { echo(points); **pasted to pt= below** echo(faces); } colors = ["red", "green", "blue", "black"]; for (i = [0:len(pts)-1]){ color(colors[i%len(colors)]) translate(pts[i]) sphere(r=.5, center=true, $fn=60); }

color
JustinSDK commented 5 years ago

path_extrude needs a way to know the time which the path projection on the XY plane makes a (nearly) 180-degree turn and does some modification on connecting points. I've tried some strategies these days but no perfect one.

PaulF8080 commented 5 years ago

I'm having fun playing with your library and thought I would try debugging this. I got lost in the path_extrude code. I may try a pull request for feature I am trying to add. I haven't figured out the pull request process, though.

JustinSDK commented 5 years ago

I'm thinking that Quaternion might have chance to fix this issue.

JustinSDK commented 5 years ago

It seems that my recent idea works. Keep working on it. issue

JustinSDK commented 5 years ago

Finally, I fix it...XDXDXD

擷取

TLC123 commented 5 years ago

How did you solve it. Is it a a general solution for arbitrary paths and cross sections?

lorf commented 5 years ago

Awesome! Thank You!

JustinSDK commented 5 years ago

@TLC123 The basic idea is shown below: issue3

In my opinion, there's no general solution for arbitrary paths because a path doesn't provide enough information about how to move sections. You may only try to find an acceptable solution without obvious bugs.

(Yes, I hope the current solution has no obvious bugs ^^ )

JustinSDK commented 5 years ago

I add a method parameter to path_extrude. See issue #5 .