Community
3ds Max Programming
Welcome to Autodesk’s 3ds Max Forums. Share your knowledge, ask questions, and explore popular 3ds Max SDK, Maxscript and Python topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Problem with curve point tangents.

14 REPLIES 14
SOLVED
Reply
Message 1 of 15
dmitriy.shpilevoy
726 Views, 14 Replies

Problem with curve point tangents.

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
)

 

 

14 REPLIES 14
Message 2 of 15

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”.

Message 3 of 15

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

Message 4 of 15


@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

Message 5 of 15

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

 

Message 6 of 15

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?

 

Message 7 of 15

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.

Message 8 of 15

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.

Message 9 of 15

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.

Message 10 of 15

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.

Message 11 of 15


@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?

 

Message 12 of 15

 

			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,

 

Message 13 of 15

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

[-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.

Message 15 of 15

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.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report