Orientation
1536 8 2- Aeva
- Member
- 5 posts
- Joined: 12月 2020
- Offline
- Aizatulin
- Member
- 480 posts
- Joined: 7月 2005
- Offline
- Konstantin Magnus
- Member
- 670 posts
- Joined: 9月 2013
- Offline
Hi Aeva,
you can identify crossings by the number of point neighbours:
The average position of the neigbour points subtracted by the crossing position will give you the normal direction. The up vector I simply set to the Z-axis in this case:
you can identify crossings by the number of point neighbours:
neighbourcount(0,@ptnum)==3
The average position of the neigbour points subtracted by the crossing position will give you the normal direction. The up vector I simply set to the Z-axis in this case:
int pts[] = neighbours(0, i@ptnum); vector pos = 0.0; foreach(int pt; pts){ pos += point(0, 'P', pt); } v@up = {0,0,1}; v@N = normalize(pos / float(len(pts)) - v@P);
https://procegen.konstantinmagnus.de/ [procegen.konstantinmagnus.de]
- Aeva
- Member
- 5 posts
- Joined: 12月 2020
- Offline
- HGaal
- Member
- 102 posts
- Joined: 6月 2023
- Offline
I would solve the problem stupidly head-on.
The intersection is a point with 3 neighbors. You have three vectors from the intersection to the neighbors. Two vectors are parallel and one is perpendicular. We need to use perpendicular to set the normal, right? So we use dot product between vectors to neighbors 0, 1, 2 (let's call these vectors v0, v1, v2). Parallel vectors will give the result "-1", perpendicular will give "0". If dot(v0,v1) == "-1", then the desired vector is the remaining one, i.e. v2. You need to exclude two vectors whose dot product = "-1" and take the remaining one. A few if's in wrangle and it's done.
The intersection is a point with 3 neighbors. You have three vectors from the intersection to the neighbors. Two vectors are parallel and one is perpendicular. We need to use perpendicular to set the normal, right? So we use dot product between vectors to neighbors 0, 1, 2 (let's call these vectors v0, v1, v2). Parallel vectors will give the result "-1", perpendicular will give "0". If dot(v0,v1) == "-1", then the desired vector is the remaining one, i.e. v2. You need to exclude two vectors whose dot product = "-1" and take the remaining one. A few if's in wrangle and it's done.
- viklc
- Member
- 143 posts
- Joined: 5月 2017
- Offline
If you want to prerotate your mesh arbitrarily, you can try the enhanced approach:
int nbs[] = neighbours(0, @ptnum); vector dir = 0; vector tan = 0; if (len(nbs) > 2) { foreach (int j; int nb; nbs) { vector pos_a = point(0, "P", nb); vector pos_b = point(0, "P", nbs[(j + 1) % 3]); float a = abs(dot(@P, pos_a - @P)); float b = abs(dot(@P, pos_b - @P)); // Precision fix a = rint(a * 1000); b = rint(b * 1000); if (a - b == 0) { // If a - b is 0, the neighboring points lie on a line. // These are avoided and the remaining point shows the // normal direction from the current position tan = normalize(point(0, "P", nb) - @P); dir = normalize(point(0, "P", nbs[(j - 1) % 3]) - @P); break; } } p@orient = quaternion(maketransform(tan, dir)); }
Edited by viklc - 2023年11月15日 04:07:33
- Aeva
- Member
- 5 posts
- Joined: 12月 2020
- Offline
- viklc
- Member
- 143 posts
- Joined: 5月 2017
- Offline
Aeva
Oh definitely this helps alot thanks!! But at certain curve conditions it doesnt works the same, but more or less works for most conditions. For those specific conditions it works well if i rather pre rotate the mesh and operate.
This appers when the intial point lies exactly on zero. A quick fix would be to simply remove/enable the "break;" command. I'll take a closer look later.
... dir = normalize(point(0, "P", nbs[(j - 1) % 3]) - @P); //break;
Edited by viklc - 2023年11月15日 04:23:09
- viklc
- Member
- 143 posts
- Joined: 5月 2017
- Offline
This should now work under any condition.
int nbs[] = neighbours(0, @ptnum); if (len(nbs) > 2) { vector dir = 0; vector tan = 0; foreach (int j; int nb; nbs) { vector nb_crt = normalize(point(0, "P", nb) - @P); vector nb_nxt = normalize(point(0, "P", nbs[(j + 1) % 3]) - @P); float dot = dot(nb_crt, nb_nxt); if (int(rint(dot))) { dir = normalize(point(0, "P", nbs[(j - 1) % 3]) - @P); tan = nb_crt; break; } } p@orient = quaternion(maketransform(tan, dir)); }
Edited by viklc - 2023年11月16日 04:50:04
-
- Quick Links