0

I'm basically trying to create 2D lines based on points from bezier curves. All the points of the bezier curves are well placed and everything seems in order. Starting with these points I'm creating 2 other points on the z axis which will be the border of the line :

 glm::vec3 p1 = pos[i]; p1.z = p1.z + (size / 2); glm::vec3 p2 = pos[i]; p2.z = p2.z - (size / 2); 

Then I change these points positions by rotating them around the main point :

pm is the mobile point rotating around the fix point pf

 glm::vec3 rotP = glm::vec3(0.0f, 0.5f, 0.0f); float co = cos(angle); float si = sin(angle); // CLOCKWISE rotP.x = (pf.x - pm.x) * co + (pf.z - pm.z) * si + pm.x; rotP.z = -(pf.x - pm.x) * si + (pf.z - pm.z) * co + pm.z; 

angle is the angle between the backward and forward point on the bezier curve :

depForward is x, glm::vec3(1.0f, 0.0f, 0.0f)

 glm::vec3 normForwardUnit = normalize(p2 - p1); float angle = (acos(dot(depForward, normForwardUnit))); 

The problem that I get is that the rotations are wrong. Some of my lines are correct but it seems to depend on the orientation of the lines.

not correct example correct example

I think the problem comes from the format of the rotation but I'm still unable to understand. I tried to normalize the angle to different ranges :

//0 to 2PI if (angle < 0) { angle += 2 * PI; } //-PI to PI if (angle > PI) { angle -= 2 * PI; } else if (angle <= -PI) { angle += 2 * PI; } 

Other ways to calculate the angle :

 float angle = atan2(p2.z - p1.z, p2.x - p1.x); 

To rotate the points counter-clockwise :

//COUNTER CLOCKWISE rotP.x = (pf.x - pm.x) * co - (pf.z - pm.z) * si + pm.x; rotP.z = (pf.x - pm.x) * si + (pf.z - pm.z) * co + pm.z; 
2
  • 1
    I'm not sure why you're trying to do rotations here. It seems to me like all you want is to create points that give your line thickness. That would be achieved by generating at a set distance perpendicular to your line. You can generate a perpendicular vector using the cross product. By crossing p2 - p1 with the Z-axis, you'll get a perpendicular vector. Or just switch the X/Y values and negate one of them. Same thing. Then normalize it, multiply by +/- the thickness. These are the offsets of your border points from the line. Commented Dec 14, 2022 at 20:53
  • Thanks @paddy, indeed it's a good way to do what I wanted. Here's the code to complete your approach : backP and nextP being the point before and the point after ' // VEC FORWARD VECTOR glm::vec3 forwardVec = normalize(backP - nextP); //PERPENDICULAR VEC glm::vec3 perpVec = cross(forwardVec, glm::vec3(0.0f, 1.0f, 0.0f)); perpVec = normalize(perpVec); //MID POINT glm::vec3 midP = midPoint(backP, nextP); glm::vec3 p1 = midP + (width * perpVec); glm::vec3 p2 = midP - (width * perpVec);' Commented Dec 15, 2022 at 15:41

2 Answers 2

1

In case anyone needs it, here's the implementation of paddy's approach. You could use the point between backP and nextP instead of midPoint to place your new points.

backP and nextP being the point before and the point after of the b curve

 // VEC FORWARD VECTOR glm::vec3 forwardVec = normalize(backP - nextP); //PERPENDICULAR VEC glm::vec3 perpVec = cross(forwardVec, glm::vec3(0.0f, 1.0f, 0.0f)); perpVec = normalize(perpVec); //MID POINT glm::vec3 midP = midPoint(backP, nextP); // GEN POINTS glm::vec3 p1 = midP + (width * perpVec); glm::vec3 p2 = midP - (width * perpVec); 
Sign up to request clarification or add additional context in comments.

Comments

0

I think you should definately look at this:

In case you insist on your way you do not need to use any angles nor rotations...

You have line p0,p1 which is sampled from your polynomial curve so:

tangent = p1-p0 

However its better to have better approximation of tangent so either take it by 1st derivation of your curve or use 2 consequent lines (p0,p1) , (p1,p2) then tangent at point p1 is:

tangent = p2-p1 

For more info see:

Now take bitangent (z axis of your camera which can be extracted from camera matrix) and use cross product to get normal

normal = normalize(cross(tangent,binormal)) 

now you just displace the p1 by normal:

p1' = p1 + 0.5*curve_thickness*normal p1'' = p1 - 0.5*curve_thickness*normal 

do the same for all points of your curve ... after that you just render quads using p' and p'' points ...

However with this approach you might run into problems that might need further tweaking see:

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.