Announcements

Between mid-October and November, the content on AREA will be relocated to the Autodesk Community M&E Hub and the Autodesk Community Gallery. Learn more HERE.

Problem with curve point tangents.

Problem with curve point tangents.

dmitriy.shpilevoy
Collaborator Collaborator
1,284 Views
14 Replies
Message 1 of 15

Problem with curve point tangents.

dmitriy.shpilevoy
Collaborator
Collaborator

Hi folks. I have couple of questions regarding point tangents.

 

1 How to ensure tangents end up as intended?

I assume it's related to tangents being close to limits. It becomes "order-sensitive". If I set inTangent before outTangent for point 3, it looks as if it was bezier-corner because inTangent is forced to 0.

In this case I can just hack it by changing order, but if I would try to create a curve with unknown number of bezier-smooth points it would be a problem.

dmitriyshpilevoy_1-1727683623477.png

 

 

2 What am I doing wrong here?

Tangents are broken for point 2. X is 0 even though in this point it's small enough to stay within limits.

dmitriyshpilevoy_0-1727683485292.png

 

 

(
rollout roll_test "rolName" (

CurveControl cc_test "Curve Control:"
height:400
width:400
align:#center
numCurves:1
visible:true
x_range:[0,1]
y_range:[0,1]
scrollValues:[0,0]
commandMode:#move_xy

button b_dumpInfo "dump info"

	on roll_test open do (
		with undo off (
			local crv1 = cc_test.curves[1]
			crv1.width = crv1.disabledWidth = 2
			crv1.color = blue
			crv1.style = #solid
			crv1.numPoints = 4
			crv1.points[1].value = [0.0, 0.0]
			crv1.points[2].value = [0.4,0.1]
			crv1.points[2].corner = false
			crv1.points[2].bezier = true
			crv1.points[2].inTangent = [-0.04,-0.04]
			crv1.points[2].outTangent = [0.04,0.04]
			crv1.points[3].value = [0.6,0.9]
			crv1.points[3].corner = false
			crv1.points[3].bezier = true
			crv1.points[3].outTangent = [0.11,0.11]
			crv1.points[3].inTangent = [-0.11,-0.11]
			crv1.points[4].value = [1.0, 1.0]

			zoom cc_test #all
		)
	)

	on b_dumpInfo pressed do (
		crv = cc_test.curves[1]

		for i = 1 to crv.numPoints do (
			format "% .value %\n" i (crv.points[i].value)
			format "% .inTangent %\n" i (crv.points[i].inTangent)
			format "% .outTangent %\n" i (crv.points[i].outTangent)
			format "---\n"
		)
	)

)

createdialog roll_test 500 526
)

 

 

0 Likes
Accepted solutions (1)
1,285 Views
14 Replies
Replies (14)
Message 2 of 15

denisT.MaxDoctor
Advisor
Advisor

I don't see anything wrong with the curve control behavior. Everything is absolutely correct. Perhaps you are missing the fact that a curve cannot overlap on the t (horizontal) direction. Because that means #time (or #param). So the tangents are adjusted every time to prevent this “overlapping”.

0 Likes
Message 3 of 15

denisT.MaxDoctor
Advisor
Advisor

Another potential source of confusion is #constrainY, which limits tangent behavior. By default, it is set to ON, but you can turn it OFF by specifying control's flags without #constrainY. (see the Help for details).

0 Likes
Message 4 of 15

dmitriy.shpilevoy
Collaborator
Collaborator

@denisT.MaxDoctor wrote:

I don't see anything wrong with the curve control behavior. Everything is absolutely correct. Perhaps you are missing the fact that a curve cannot overlap on the t (horizontal) direction. Because that means #time (or #param). So the tangents are adjusted every time to prevent this “overlapping”.


I'm definitely missing something here, though not even sure what exactly. Don't understand why tangents are changed from values I'm trying to feed my curve on creation.

 

I set those tangents to in [-0.04,-0.04] and  out [0.04,0.04] for second point, in [-0.11,-0.11] and out [0.11,0.11] for the third one. Third one looks as I expect it to and when I read its tangents back, values are the same (with very small error like 0.1 and 0.121, but for my needs it's close enough), while second point looks very different from what I intended for it and after dumping its tangents I can see both tangents have their X at 0 for some reason.

Tried uiFlags:#(#drawBG, #drawgrid, #upperToolbar, #showReset, #scrollBars, #xvalue) but second point's tangents are still the same. What should I do to have them as shown in green instead of red?

 

tang_01e.png

0 Likes
Message 5 of 15

denisT.MaxDoctor
Advisor
Advisor

But the points are not #corners... their tangents are “bound” together, and they both change if you change one of them.
Try making them #corner and you'll see how they can work independently (and give you the numbers you expect).

denisTMaxDoctor_0-1727804849281.png

 

0 Likes
Message 6 of 15

dmitriy.shpilevoy
Collaborator
Collaborator

I'm so confused...

 

Made 2nd and 3rd points bezier-corner. 3rd is visually unchanged, 2nd now has correct inTangent, but outTangent still has its X set to 0.

dmitriyshpilevoy_0-1727844627780.png

 

Thought that if tangents are bound I can only set in or out and the other one would get adjusted accordingly. Commented out outTangent for 2nd and 3rd points:

dmitriyshpilevoy_1-1727845015991.png

Both points are still technically bezier-smooth, but now everything is 0 apart from 2nd point's X. Where is this inconsistency coming from? Shouldn't both points behave in same way?

It looks like I do need to explicitly specify both - in and out tangents. Yet even if precisely opposite (in [-0.04,-0.04] and  out [0.04,0.04]) they are still affecting each other in unexpected way.

 

Is there a fundamental flaw in my code or the way I approach curve creation?

 

0 Likes
Message 7 of 15

denisT.MaxDoctor
Advisor
Advisor

Let's clarify everything. What are you trying to achieve? Are you trying to create a curve with specific points and their tangents? If you don't use the #corner point type, the tangents will be constrained, meaning you won't be able to set any values you want. If you use #constrainY, you won't be able to set the tangent in a way that the handle extends beyond the Y borders. Additionally, you won't be able to adjust the tangents or the position of the points, which may result in the curve overlapping in the param (t or X) coordinate.

0 Likes
Message 8 of 15

denisT.MaxDoctor
Advisor
Advisor

I can only say that there is nothing wrong with the Curve control behavior, but I have to agree that it does not follow a logical and intuitive interface design. This is why, about 15 years ago, I rewrote it my way.

0 Likes
Message 9 of 15

denisT.MaxDoctor
Advisor
Advisor

Years ago, we discussed all the issues with Curve control on CGTalk, and I demonstrated how to use a bezier-float controller instead. Unfortunately, the forum is dead now, and it will be hard to find that thread.

0 Likes
Message 10 of 15

dmitriy.shpilevoy
Collaborator
Collaborator

I want a curve that looks like this.
It's static and won't change dynamically.
User should be able to modify and reset it by hand.

Should not allow to move points or tangents beyond Y border.

dmitriyshpilevoy_0-1727847446932.png

 

First, I made curve by hand (as on the pic above) and dumped info for every point. Then I tried to use those values to create same curve with script and that's where I got stuck because result looks nothing like what I'm trying to recreate.

0 Likes
Message 11 of 15

denisT.MaxDoctor
Advisor
Advisor

@dmitriy.shpilevoy wrote:

 

First, I made curve by hand (as on the pic above) and dumped info for every point. Then I tried to use those values to create same curve with script and that's where I got stuck because result looks nothing like what I'm trying to recreate.


that sounds odd... let me try.

 

what are the initial values you want to use?

 

0 Likes
Message 12 of 15

dmitriy.shpilevoy
Collaborator
Collaborator

 

			crv1.points[2].value = [0.4,0.1]
			crv1.points[2].corner = false
			crv1.points[2].bezier = true
			crv1.points[2].inTangent = [-0.106951,-0.0888888]
			crv1.points[2].outTangent = [0.123631,0.102752]
			crv1.points[3].value = [0.6,0.9]
			crv1.points[3].corner = false
			crv1.points[3].bezier = true
			crv1.points[3].inTangent = [-0.12255,-0.112844]
			crv1.points[3].outTangent = [0.108602,0.1]

This is what I get from curve created by hand. In final code would prefer to use [-0.11,-0.11] and [0.11,0.11] so it would look nice and tidy,

 

0 Likes
Message 13 of 15

denisT.MaxDoctor
Advisor
Advisor
Accepted solution

ok ...  here is how to do it:

 

try (destroyDialog rol) catch()

rollout rol "CurveTable" width:400 height:300
(
	CurveControl cc "" align:#left offset:[-12,5] asPopup:off width:380 height:280
		numCurves:1
		x_range:[0,1] 
		y_range:[0,1] 
		scrollValues:[-133,-38] 
		zoomValues:[220,200]
		commandMode:#move_xy 
		rcmFlags:#(#move_xy, #move_x, #move_y, #corner, #bezier, #delete, #all) 
		uiFlags:#(#drawBG, #drawgrid, #upperToolbar, #lowerToolbar, #scrollBars, #xvalue, #ruler, #hideDisabled, #autoScroll, #constrainY)
	
	fn dumpInfo = 
	(
		crv = cc.curves[1]

		for i = 1 to crv.numPoints do (
			format "% .value %\n" i (crv.points[i].value)
			format "% .inTangent %\n" i (crv.points[i].inTangent)
			format "% .outTangent %\n" i (crv.points[i].outTangent)
			format "---\n"
		)
	)	
	
	on rol open do
	(
		local crv1 = cc.curves[1]
		crv1.width = crv1.disabledWidth = 2
		crv1.color = blue
		crv1.style = #solid
		crv1.numPoints = 2
		
		crv1.points[1].value = [0.0, 0.0]
		crv1.points[2].value = [1.0, 1.0]
		
		cp2 = ccPoint [0.4,0.1] [-0.106951,-0.0888888] [0.123631,0.102752] bezier:true
		cp3 = ccPoint [0.6,0.9] [-0.12255,-0.112844] [0.108602,0.1] bezier:true
		
		insertPoint crv1 2 cp2  
		insertPoint crv1 3 cp3  
		
		zoom cc #all
	)
)
createdialog rol

 

 

"Don't wonder why; just take it as it is."  (c) 😁

Message 14 of 15

denisT.MaxDoctor
Advisor
Advisor

[-0.11,-0.11] [0.11,0.11] are out of bounds for both points... this can be created as is, but will be adjusted once touched.

0 Likes
Message 15 of 15

dmitriy.shpilevoy
Collaborator
Collaborator

Pure magic! Thank you, Denis.

 

Oh right, 0.9 + 0.11 would send it above Y border. Well, I'm fine with [-0.1, -0.1] [0.1, 0.1] or even [-0.08, -0.08] [0.08, 0.08]. Predictable and consistent tangent creation will allow me to experiment without losing my mind now.

0 Likes