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

How to sample ICurveGeo evenly based on the curve length? not the u coordinates #21

Open
chatyan opened this issue Apr 7, 2019 · 2 comments

Comments

@chatyan
Copy link

chatyan commented Apr 7, 2019

Hi, I am new to this great library.
Currently, I want to get sampling points evenly on the ICurveGeo.
I have tried to use pt(double u) function and got some points based on evenly sampling the u coordination. I just wonder if there is a way to let the user sampling points based on the arc-length of the curve, so the user can get those sampling points accurately.

Thanks a lot.
Again great library for 3D modeling in Java

@sghr
Copy link
Owner

sghr commented Apr 9, 2019

Thank you for the comment.
Unfortunately I don't have a method to sample NURBS curves evenly by the length in the XYZ space with mathematically accurate inverse calculation from XYZ to U.
What I would do is just approximate it by lengths of line segments like the code below.
You could replace the length calculation with arc-length calculation by 3 points or 2 points + tangent vectors to make it more accurate, or simply increase resolution of the line segment approximation depending on how much accuracy you need.
Thanks!
Satoru

`
import igeo.*;
size(1000,800,IG.GL);
ICurve crv = new ICurve(IG.v(0,0,0, 100,0,0, 110,50,0, 120,0,0, 50,-50,0),3);

int div = 10;
double len = 0;
// you could also use len() method, which is also linear approximation.
//double len = crv.len();
int res = 1000;
IVec prevPt = crv.pt(0);
for(int i=1; i<=res; i++){
IVec pt = crv.pt(i*1./res);
len += pt.dist(prevPt);
prevPt = pt;
}

int idx = 0;
double curlen = 0;
prevPt = crv.pt(0);
for(int i=1; i<=res; i++){
IVec pt = crv.pt(i1./res);
curlen += prevPt.dist(pt);
for(; curlen >= len/div
idx; idx++){
double ratio = (curlen - len/div*idx)/ prevPt.dist(pt);
double u = (i-ratio)/res;
new IPoint(crv.pt(u)).clr(1.,0,0);
}
prevPt = pt;
}
`

@chatyan
Copy link
Author

chatyan commented Apr 10, 2019

Your comment really helps me a lot!
Many thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants