/* * create the shortest line between two lines in 3D * from the tutorial by Paul Bourke: pbourke@swin.edu.au * http://astronomy.swin.edu.au/~pbourke/geometry/lineline3d/ * * implemented in MEL by Dan Wills: dan@rsp.com.au * Feb 2003 * * create 4 locators, make sure they are called locator 1..4 * runing this script then creates 2 more locators and 3 curves to illustrate the vectors. * */ //do the function 'd' as defined by pb. global proc float d_of(float $m[],float $n[],float $o[],float $p[]) { return ($m[0] - $n[0]) * ($o[0] - $p[0]) + ($m[1] - $n[1]) * ($o[1] - $p[1]) + ($m[2] - $n[2]) * ($o[2] - $p[2]); } //linearly interpolate 2 3d points global proc float[] inter3D(float $a[], float $b[], float $weight) { float $rezul[]; $rezul[0] = ( $weight * $b[0] ) + ( (1 - $weight) * $a[0] ); $rezul[1] = ( $weight * $b[1] ) + ( (1 - $weight) * $a[1] ); $rezul[2] = ( $weight * $b[2] ) + ( (1 - $weight) * $a[2] ); return $rezul; } //define the locators to use: string $p1 = "locator1"; string $p2 = "locator2"; string $p3 = "locator3"; string $p4 = "locator4"; //grab their translation info float $pp1[]; float $pp2[]; float $pp3[]; float $pp4[]; $pp1[0] = `getAttr ($p1 + ".translateX")`; $pp1[1] = `getAttr ($p1 + ".translateY")`; $pp1[2] = `getAttr ($p1 + ".translateZ")`; $pp2[0] = `getAttr ($p2 + ".translateX")`; $pp2[1] = `getAttr ($p2 + ".translateY")`; $pp2[2] = `getAttr ($p2 + ".translateZ")`; $pp3[0] = `getAttr ($p3 + ".translateX")`; $pp3[1] = `getAttr ($p3 + ".translateY")`; $pp3[2] = `getAttr ($p3 + ".translateZ")`; $pp4[0] = `getAttr ($p4 + ".translateX")`; $pp4[1] = `getAttr ($p4 + ".translateY")`; $pp4[2] = `getAttr ($p4 + ".translateZ")`; //create the two base curves curve -d 1 -ws -p $pp1[0] $pp1[1] $pp1[2] -p $pp2[0] $pp2[1] $pp2[2]; curve -d 1 -ws -p $pp3[0] $pp3[1] $pp3[2] -p $pp4[0] $pp4[1] $pp4[2]; //caluclate the parpametric position on the 2 curves, mua and mub float $mua = ( d_of($pp1,$pp3,$pp4,$pp3) * d_of($pp4,$pp3,$pp2,$pp1) - d_of($pp1,$pp3,$pp2,$pp1) * d_of($pp4,$pp3,$pp4,$pp3) ) / ( d_of($pp2,$pp1,$pp2,$pp1) * d_of($pp4,$pp3,$pp4,$pp3) - d_of($pp4,$pp3,$pp2,$pp1) * d_of($pp4,$pp3,$pp2,$pp1) ); float $mub = ( d_of($pp1,$pp3,$pp4,$pp3) + $mua * d_of($pp4,$pp3,$pp2,$pp1) ) / d_of($pp4,$pp3,$pp4,$pp3); //clip the value between [0..1] constraining the solution to lie on the original curves if ($mua < 0) $mua = 0; if ($mub < 0) $mub = 0; if ($mua > 1) $mua = 1; if ($mub > 1) $mub = 1; //get the actual transforms by linearly interpolating float $muap[]; float $mubp[]; $muap = inter3D($pp1,$pp2,$mua); $mubp = inter3D($pp3,$pp4,$mub); //create a locator on both points $sl = `spaceLocator`; move $muap[0] $muap[1] $muap[2] $sl; $sl = `spaceLocator`; move $mubp[0] $mubp[1] $mubp[2] $sl; //create a curve between them curve -d 1 -ws -p $muap[0] $muap[1] $muap[2] -p $mubp[0] $mubp[1] $mubp[2];