Geometrical calculations : points, lines, planes : intersections, distances, angles


#21

I concur… this is really great, props to prettyPixel and everyone else that contributed!


#22

The code I use for doing a look-at type operation is:

fn PointAxisAt a which_axis b =
(
local c = normalize (b - a) 
local angle = acos (dot which_axis c)
local axis = normalize (cross which_axis c)
 
local out = (angleaxis angle axis) as quat
out
)
 
a = $Pyramid01.position
b = $Point01.position
q = PointAxisAt a z_axis b
r = q * (inverse $Pyramid01.rotation)
rotate $Pyramid01 r

#23

THought this might be the best topic to post it:

I have this camera data:
posz=-12.896441
posy=10.177296
posx=-248.952271

And this for the angle:
anglez=1.000000
angley=0.000000
anglex=0.000000

this is how they calculated the angle:
angle = camera_target - camera
angle = normalize angle
anglex = angle.x
angley = angle.y
anglez = angle.z

how would i go about transforming the angle from this data?
how can i create a target or free camera from this?


#24

I prefer to rename “angle” in “direction” because the angle can remind the angle of the camera (fov)

thePos = [posx,posy,posz]
theDirection = [directionx,directiony,directionz]
theLength = 100.0
theTargetPos = thePos + ((normalize theDirection)*theLength)

myCam = targetCamera pos:thePos target:(targetObject pos:theTargetPos)

Regrettably your data are not complete : the camera’s FOV is missing.


#25

Thanks for your reply but i already solved it. I did it slightly different though:

camera_target_position = point3 (posx + directionx10) (posy + directiony10) (posz + directionz*10)

Which returns the correct ‘direction’.

Oh and you dont need a FOV to create a camera, it uses default setting when you leave it out.


#26

I just wanna give you two link for resources about geometry (intersections , distance computations etc):

http://www.softsurfer.com (algorithms section)
http://www.geometrictools.com

Hope this helps


#27

Great thread! Seeing basic concepts as code snippets is fantastic!

I do think that the posting of questions (as opposed to answers) clutters the “repository” feel, though. For those asking (new and unrelated) questions wouldn’t it be more helpful to start and finish a new thread, THEN post (a concise answer) here?

:smiley:


#28

This is being transferred to the CGWiki bit by bit, so the information can be kept clean:
http://wiki.cgsociety.org/index.php/Geometric_Calculations_(3dsmax)


#29

Hy all,

I am new at maxscript and I want to calculate the shortest distance between a vertex in a skin and a bone. Can someone help me?

-edit-

ok, i modified pretty pixel’s code and got this:



fn pointSegmentDist pA pB pC = 
(
	local vAB=pB-pA
	local vAC=pC-pA
	local vBC=pC-PB
	
	local c1=dot vAB vAC
	local c2=dot vAB vAB
	
	if c1 < 0 do
		return length vAC
	
	if c2 < c1 do
		return length vBC
	
	(length (cross vAB vAC))/(length vAB)
)

not sure if it is 100% correct, i have other issues but will start a new thread for that.


#30

The Algorithmic Beauty of Plants can be downloaded here as PDF:
http://algorithmicbotany.org/papers/

This is the ‘definitve book’ about L-Systems (see also Challenge #16).
Sometimes you can find a printed version in ‘antique shops’ - get it!
I ordered mine some weeks ago, hope it arrives soon …

Georg


#31

this is a maxscript version of Robert Penners Easing Equotations for Flash:

struct rpEFn (
 	-- ---
 	-- Easing Equotations by Robert Penner
 	-- http://www.robertpenner.com/
 	-- The BSD License: http://www.opensource.org/licenses/bsd-license.php
 	-- ---
 	-- maxScript port by Georg Duemlein
 	-- 2007-04-18
 	-- http://www.preset.de
 	-- ---
 	-- previews: http://www.gizma.com/easing/
 	-- ---
 	-- t: current time
 	-- b: start value
 	-- c: end value
 	-- d: duration
 	-- ---
 	-- simple linear tweening - no easing, no acceleration
 	fn linearTween t b c d = (
 			c*t/d + b
 	),
 	--  quadratic easing in - accelerating from zero velocity
 	fn easeInQuad t b c d = (
 		t /= d
 		c*t*t + b
 	),
 	-- quadratic easing out - decelerating to zero velocity
 	fn easeOutQuad t b c d = (
 		t /= d
 		-c * t * (t-2) + b
 	),
 	-- quadratic easing in/out - acceleration until halfway, then deceleration
 	fn easeInOutQuad t b c d = (
 		t /= d/2
 		if (t < 1) then (
 			c / 2 * t * t + b
 		)else(
 			t-=1
 			-c / 2 * (t* (t - 2) - 1) + b
 		)
 	),
 	-- cubic easing in - accelerating from zero velocity
 	fn easeInCubic t b c d = (
 		t /= d
 		c*t*t*t + b
 	),
 	-- cubic easing out - decelerating to zero velocity
 	fn easeOutCubic t b c d = (
 		t /= d
 		t-=1
 		c*(t*t*t + 1) + b
 	),
 	-- cubic easing in/out - acceleration until halfway, then deceleration
 	fn easeInOutCubic t b c d = (
 		t /= d/2
 		if (t < 1) then (
 			c/2*t*t*t + b
 		)else(
 			t -= 2
 			c/2*(t*t*t + 2) + b
 		)
 	),
 	-- quartic easing in - accelerating from zero velocity
 	fn easeInQuart t b c d = (
 		t /= d
 		c*t*t*t*t + b
 	),
 	-- quartic easing out - decelerating to zero velocity
 	fn easeOutQuart t b c d = (
 		t /= d
 		t -= 1
 		-c * (t*t*t*t - 1) + b
 	),
 	-- quartic easing in/out - acceleration until halfway, then deceleration
 	fn easeInOutQuart t b c d = (
 		t /= d/2
 		if (t < 1) then(
 			c/2*t*t*t*t + b
 		)else(
 			t -= 2
 			-c/2 * (t*t*t*t - 2) + b
 		)
 	),
 	-- quintic easing in - accelerating from zero velocity
 	fn easeInQuint t b c d = (
 		t /= d
 		c*t*t*t*t*t + b
 	),
 	-- quintic easing out - decelerating to zero velocity
 	fn easeOutQuint t b c d = (
 		t /= d
 		t -= 1
 		c*(t*t*t*t*t + 1) + b
 	),
 	-- quintic easing in/out - acceleration until halfway, then deceleration
 	fn easeInOutQuint t b c d = (
 		t /= d/2
 		if (t < 1) then (
 			c/2*t*t*t*t*t + b
 		)else(
 			t -= 2
 			c/2*(t*t*t*t*t + 2) + b
 		)
 	),
 	-- sinusoidal easing in - accelerating from zero velocity
 	fn easeInSine t b c d = (
 		-c * cos (t/d * (180 / 2)) + c + b
 	),
 	-- sinusoidal easing out - decelerating to zero velocity
 	fn easeOutSine t b c d = (
 		c * sin (t/d * 90) + b
 	),
 	-- sinusoidal easing in/out - accelerating until halfway, then decelerating
 	fn easeInOutSine t b c d = (
 		-c/2 * (cos(180 * t/d) - 1) + b
 	),
 	-- exponential easing in - accelerating from zero velocity
 	fn easeInExpo t b c d = (
 		c * pow 2 (10 * (t/d - 1)) + b
 	),
 	-- exponential easing out - decelerating to zero velocity
 	fn easeOutExpo t b c d = (
 		c *  (-pow 2 (-10 * t/d) + 1 ) + b
 	),
 	-- exponential easing in/out - accelerating until halfway, then decelerating
 	fn easeInOutExpo t b c d = (
 		t /= d/2
 		if (t < 1) then (
 			c / 2 * pow 2 (10. * (t - 1)) + b
 		)else(
 			t -= 1
 			c / 2 *  (-pow 2 (-10. * t) + 2 ) + b
 		)
 	),
 	-- circular easing in - accelerating from zero velocity
 	fn easeInCirc t b c d = (
 		t /= d
 		-c * (sqrt(1 - t*t) - 1) + b
 	),
 	-- circular easing out - decelerating to zero velocity
 	fn easeOutCirc t b c d = (
 		t /= d
 		t -= 1
 		c * sqrt(1 - t*t) + b
 	),
 	-- circular easing in/out - acceleration until halfway, then deceleration
 	fn easeInOutCirc t b c d = (
 		t /= d/2
 		if (t < 1) then (
 			-c/2. * (sqrt(1. - t*t) - 1.) + b
 		)else(
 			t -= 2
 			c/2. * (sqrt(1. - t*t) + 1.) + b
 		)
 	)
 )
 
 -- sample
 d = 50.
 t = 0.
 	
 while t < d do (
 	v1 = v2 = v3 = 0
 	v1 = rpEFn.linearTween t 0. 100. d
 	v2 = rpEFn.easeInOutQuad t 1. 100. d
 	v3 = rpEFn.easeInOutQuad t 0. 1. (d/2)
 	sp = sphere pos:[v1, 0, v2] radius:(.5 + v3)
 	sp.wirecolor = [255,255,255] * v3
 	-- ---
 	t += .5
 	max zoomext sel all
 )
 

maybe this is usefull for somebody

http://www.robertpenner.com/
http://www.gizma.com/easing/

2007-05-08
I found this API documentation:
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/fl/transitions/easing/Elastic.html
and c is the “total change in the animation property”.

I also recomend the “Tweening chapter of my book” at Robert Penners site.
I just started reading it and it explains a lot.

Georg


#32

Hey people, lovely math here :slight_smile: heheh i’v forgotten most of it heheh.
I’m trying now to get the angle between 2 points.

So i looked in the reference. there it says the following :
to calculate the angle use the following formula :
theAngle = acos(dot (normalize v1) (normalize v2))

So i tried this in max. if i select 0.0.0 and 150.661,150.661,0 i get 45. till now all okey.
But if i select [size=2]10,10,0 and 150.661,150.661,0 i get 0.0197823[/size]
[size=2][/size]
[size=2]Hmmmmm why?[/size]
[size=2]for both two the angle should be 45. but i get different results.
Any1 who can shed some light on this ?[/size]
[size=2][/size]
[size=2]Many thx in advance![/size]
[size=2][/size]


#33

Very strange to get [size=2]0.0197823, you should get 0 since the vectors are pointing in the same direction(the angle between them is 0 :slight_smile: ). Maybe its a float point accuracy problem at the normalization(1 inversion, 3 multiplies and one square root) and the acos. But anyway, the formula is correct.
[/size]


#34

The normalize function returns a unit vector, meaning that it’s length equals 1 unit. Normalizing [0,0,0] will return [1,0,0], so this explains why the result of your first example is 45. Your second example should return 0, but returns 0.0197823 instead because of round-off errors.

1. [0,0,0] [150.661,150.661,0]
   == [1,0,0] [0.707107,0.707107,0] (normalized)
   == 45

2. [10,10,0] [150.661,150.661,0]
   == [0.707107,0.707107,0] [0.707107,0.707107,0] (normalized)
   == 0

Hope this helps,
Martijn


#35

Nice thread!

Any idea in how to test if a point is inside a n-dimensional polyhedron just by coordinates? If one has all the vertexes coordinates of a 3d solid and a point3, how to check if the point3 is inside?

cheers


#36

I don’t have the complete solution but some ideas:

First try a fast test : find if the point is completely outside the volume by using the distance.
For example: you find the center of the bounding box of the volume and the point which is farthest. If your point is farther then it is not inside the volume. It’s obvious but that avoid to apply a complex function each time…

After… I’m not sure that is 100% secure but if you use the normal of the faces I think we can have a good approach to do that.
For a convex volume, a point is inside a volume if this point is behind of each face of the volume.
For each face:

  • find the vector of the point-plane projection of the face
  • calculate if the vector have the same direction than the normal of the face
  • if all vectors have the same direction then your point is inside the convex volume

The problem appears when you have a non-convex volume.
For example imagine a form like a “U” (in 3D)
If your point is at the center of the U, ok that does work because the point is really outside the volume in itself.
… but if the point is inside of the volume then there are several faces where the normal is in opposite direction of the vector of the point-plane projection.

Probably the solution is to divide the concave volume in several convex volumes. After you test for each convex volume if the point is inside or not and you stop as soon as you find a point inside…


#37

I had another idea.
If the point is inside the volume, you can trace a ray to any direction and you intersect a face.
You compare the 2 vectors (your ray and the face normal) and if the sign of the dot product is positive then your point is inside the volume. And that could work for a concave volume :slight_smile:


#38

hello,
nice one with the geometry, and thanks for starting such a thread,does anyone know how to find the intersection of a plane(or a cube, or polyhedra) and a spline?


#39

Hello,

I had sent a question rather similar about splines but it seems that it is not possible to find a mathematical solution for a spline and the only solution is to convert your spline into on a certain number of lines or walking the spline with iterations.

Here is the thread:
http://forums.cgsociety.org/showthread.php?f=98&t=470089&page=5&pp=15

But if somebody can confirm this…


#40

hi arketip,
i also looked for the same thing for a long time -
as you say the only thing i found was subdividing by n interations and getting closest to one of these

i dont think you can do any other way