Orientation

   1536   8   2
User Avatar
Member
5 posts
Joined: 12月 2020
Offline
Hello, so i have set of lines that i wanna copy my object to but since the lines are individual prims and normals dont work accordingly for all curves as i want to. how can i align the normals to get an orientation like this. Thanks in advance!
Edited by Aeva - 2023年11月10日 09:46:08

Attachments:
Orientation.hiplc (879.6 KB)
Screenshot 2023-11-10 201045.png (35.5 KB)

User Avatar
Member
480 posts
Joined: 7月 2005
Offline
Here is one way:
the first direction should be z-axis and the other direction, should be to the neighbour, which has the closest distance to the average direction.

Attachments:
Orientation_mod.hipnc (886.2 KB)

User Avatar
Member
670 posts
Joined: 9月 2013
Offline
Hi Aeva,

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);

Attachments:
Orientation_KM.hiplc (880.1 KB)

https://procegen.konstantinmagnus.de/ [procegen.konstantinmagnus.de]
User Avatar
Member
5 posts
Joined: 12月 2020
Offline
Hello thanks a lot, appreciate it. Just wanted to confirm if it would be possible without changing the rotation of the base mesh as what i tried with a similar approach i get orientation when the copied mesh is rotated to (90,0,90)
Edited by Aeva - 2023年11月13日 03:30:54

Attachments:
Orientation_01.hipnc (877.5 KB)

User Avatar
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.
User Avatar
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

Attachments:
orient.hiplc (888.0 KB)

User Avatar
Member
5 posts
Joined: 12月 2020
Offline
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.

Attachments:
OrientationIssue.hiplc (1.6 MB)

User Avatar
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

Attachments:
OrientationHotFix.hiplc (1.6 MB)

User Avatar
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

Attachments:
OrientationElaborateFix.hiplc (2.1 MB)

  • Quick Links