home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 14 / IOPROG_14.ISO / soft / sdkjava / dxma.exe / DXMA05.cab / samples / da / java / templates / Splines / Splines.java < prev   
Encoding:
Java Source  |  1997-11-13  |  8.7 KB  |  216 lines

  1. //
  2. // <Tutorial Section=1.0 Title="Interactive Spline">
  3. //
  4. /**
  5.  Demonstrates the support for splines in DirectAnimation, including: <br>
  6.  - the correspondence between a path and behavior cubic splines, <br>
  7.  - the use of draggable points for making the spline interactive <br>
  8.  - the use of the derivative operation for obtaining the spline tangent <br>
  9.  - animating a sprite along the spline with the orientation of the tangent <br>
  10.  
  11. **/
  12.  
  13. // </Tutorial>
  14.  
  15. // <Tutorial Section=5.0 Title="Boiler Plates">
  16.  
  17. import com.ms.dxmedia.*;    // All direct Animation classes
  18. import java.net.*;          // the URL class 
  19. import java.awt.*;          // the Dimension class
  20. import java_utility.*;           // the DraggableImage class
  21.  
  22. // Splines is an applet that invokes SplinesModel to construct an
  23. // interactive spline with the specified number of polynomial pieces
  24. public class Splines extends DXMApplet {
  25.   public void init() {
  26.     super.init() ;
  27.     setModel (new SplinesModel(this, 4));
  28.   }
  29. }
  30.  
  31. //
  32. class SplinesModel extends Model {
  33.  
  34.   SplinesModel(DXMApplet dxma, int numPolys) {
  35.     _numPolys = numPolys;
  36.  
  37.     // Get the size of the viewport.
  38.     Dimension dim = dxma.getSize();
  39.     // The base unit of measure for DirectX Media is the meter.
  40.     // Convert the size into meters by multiplying it with the pixelBvr.
  41.     _halfWidth = mul(toBvr(dim.width*0.5),pixelBvr);
  42.     _halfHeight = mul(toBvr(dim.height*0.5),pixelBvr);
  43.   }  
  44.  
  45. // </Tutorial>
  46.  
  47.   public void createModel(BvrsToRun listBvrs) {
  48.     
  49. // <Tutorial Section=3.0 Title="Travelling Car along the Spline">
  50.     // build a URL to import images
  51.     URL imgBase = buildURL(getImportBase(),"image/");
  52. // </Tutorial>
  53.  
  54. // <Tutorial Section=2.0 Title="Construct an Interactive Spline">
  55. //
  56. // Construct a cubic BSpline with initial control points that are
  57. // colinear and equally spaced. The points are draggable for manipulating
  58. // the shape of the spline.
  59. // The spline is a uniform BSpline with standard end conditions,
  60. // where end points are interpolated.
  61. // The only parameter that is needed is the
  62. // number of polynomial pieces that are desired in the spline.
  63.  
  64.     // number of control points is related to the number of polynomials
  65.     int numPts = _numPolys + 3;      // number of control points >= 4
  66.  
  67.     // vertically center initial control points 
  68.     double initY = 0;
  69.     NumberBvr initX = mul(neg(_halfWidth),toBvr(0.7));    // 15% from left side
  70.     NumberBvr incX = div(mul(_halfWidth,toBvr(1.4)),toBvr((numPts - 1))); // use 70% of range
  71.  
  72.     // for the control points of the spline
  73.     Point2Bvr[] ptsPt2 = new Point2Bvr[numPts];
  74.     // 2 more knots than control points since a cubic
  75.     NumberBvr[] knotsNum = new NumberBvr[numPts + 2];    
  76.     Point2Bvr initPt2;      // initial position of a draggable
  77.     DraggableButton draggable;    // holder of a draggable point
  78.     ImageBvr ptsImg = emptyImage;  // the accumulated image
  79.  
  80.     // construct the control points and the knot vector
  81.     for (int i = 0; i < numPts; i++) {
  82.       initPt2 = point2(add(initX,mul(toBvr(i),incX)), toBvr(initY));
  83.       draggable = new DraggableButton(initPt2);
  84.       ptsPt2[i] = draggable.getPointBvr();
  85.       ptsImg = overlay(ptsImg, draggable.getImageBvr());
  86.       knotsNum[i] = toBvr(i-2);      // we want the first 3 knots to be 0, see next
  87.     }
  88.  
  89.     // Set first and last two knots to achieve multiplicity 3,
  90.     // this makes the spline pass through the first and last control points.
  91.     knotsNum[0] =  knotsNum[1] = toBvr(0);    
  92.     knotsNum[numPts] =  knotsNum[numPts + 1] = knotsNum[numPts - 1];
  93.  
  94.  
  95.     // generate images of the spline and its control polygon
  96.     Path2Bvr cubicCurvePath = cubicBSplinePath(ptsPt2, knotsNum);
  97.     Path2Bvr controlPolyPath = polyline(ptsPt2);
  98.     LineStyleBvr lLnS = defaultLineStyle.width(toBvr(0.5*mm));
  99.     ImageBvr cubicCurveImg = cubicCurvePath.draw(lLnS.color(green));
  100.     ImageBvr controlPolyImg = controlPolyPath.draw(lLnS.color(white));
  101.  
  102. // </Tutorial>
  103.  
  104. // <Tutorial Section=3.1>
  105.  
  106.     // Create an image behavior of a car by importing a bitmap.
  107.     ImageBvr car1Img = importImage(buildURL(imgBase, "car3.gif"));
  108.     // Car2 is the mirror image of car1 along Y; 
  109.     // use this later to keep the sprite upright.
  110.     ImageBvr car2Img = car1Img.transform(scale(1,-1));
  111.  
  112.     // Get an image moving back and forth along the spline,
  113.     // the spline is well defined between the third knot from the begining
  114.     // (= 0) and the third knot from the end since it is a cubic.
  115.     NumberBvr limitNum = knotsNum[numPts - 1]; // third knot from end
  116.     
  117.     // Evaluator spans the parameter space of the spline and then
  118.     // returns to the beginning. It then repeats.
  119.     NumberBvr evaluatorNum = NumberBvr.newUninitBvr();
  120.     evaluatorNum.init(until(mod(localTime, limitNum),
  121.                             timer(limitNum),
  122.                               until(sub(limitNum, mod(localTime, limitNum)),
  123.                                 timer(limitNum),
  124.                                   evaluatorNum)));
  125.  
  126.     // Construct a point2 behavior that goes back and forth along the spline.
  127.     Point2Bvr splPt2 =
  128.           bSpline(DEGREE, knotsNum, ptsPt2, null, evaluatorNum);
  129.  
  130.     // Speed is the speed of traversal of the spline;
  131.     // it switches among three values upon rightButtonDown.
  132.     NumberBvr speedNum = NumberBvr.newUninitBvr();
  133.     speedNum.init ( until(toBvr(0.6),
  134.                          rightButtonDown,
  135.                          until(toBvr(1.2),
  136.                                rightButtonDown,
  137.                                until(toBvr(1.8),
  138.                                      rightButtonDown,
  139.                                      speedNum))));
  140.     
  141.     // Construct a new point2 behavior that goes back and forth at
  142.     // the rate of "speed" along the original spline. 
  143.     // Integrate the speed and invoke substituteTime.
  144.     // The runOnce construct is necessary so that the integration does not get
  145.     // restarted everytime the rightButtonDown event occurs.
  146.     splPt2 = (Point2Bvr)splPt2.substituteTime(integral((NumberBvr)speedNum.runOnce()));
  147.     
  148.     // Orient the car based on the spline.
  149.  
  150.     // The tangent to the spline is its derivative.
  151.     // Notice that the derivative of a point behavior is a vector behavior.
  152.     Vector2Bvr tangentVec2 = derivative(splPt2);
  153.     // Extract the angle between the tangent and the X axis; 
  154.     // it is in [-PI, +PI] range.
  155.     NumberBvr angleNum = tangentVec2.getPolarCoordAngle();
  156.     // The quadrant in which the tangent lies is in [0, 1, -2, -1] CCW
  157.     NumberBvr quadrentNum = floor(div(angleNum, toBvr(Math.PI/2)));
  158.     // carImg is always upright as the traversal of the spline takes place
  159.     ImageBvr carImg = (ImageBvr)cond(or(eq(quadrentNum, toBvr(0)),
  160.                                       eq(quadrentNum, toBvr(-1))),
  161.                           car1Img,
  162.                           car2Img); 
  163.  
  164.     // construct a car that travels along the spline always upright
  165.     ImageBvr movingCarImg = carImg.transform(compose(translate(sub(splPt2, origin2)), 
  166.                                                      rotate(angleNum)));
  167.     
  168.     // Finally, combine all these parts into the final model.
  169.     setImage(overlay(movingCarImg,
  170.                overlay(cubicCurveImg, 
  171.                  overlay(ptsImg, 
  172.                    overlay(controlPolyImg, solidColorImage(blue))))));
  173.   }
  174.   
  175.   private static int DEGREE = 3;  // only cubic pathes are supported
  176.   private int _numPolys;          // number of polynomials in the spline
  177.   
  178. // </Tutorial>
  179.  
  180. // <Tutorial Section=5.1>
  181.   private NumberBvr _halfWidth;      // half width of viewport
  182.   private NumberBvr _halfHeight;     // half height of viewport
  183.  
  184. // </Tutorial>
  185. }
  186.  
  187. // <Tutorial Section=4.0 Title="Using Draggables for Control Points">
  188.  
  189. //
  190. // Here, use the draggable class from the utility library.
  191. // Construct a draggable based on a small (4 mm) cube with a reactive color
  192. // the color is green while dragged and red otherwise. Provide accessors to get
  193. // back the image and the position point of the draggable.
  194. //
  195.  
  196. class DraggableButton extends Statics {
  197.  
  198.   public DraggableButton(Point2Bvr initPt2) {
  199.  
  200.     NumberBvr halfDimNum = toBvr(2*mm); 
  201.     ColorBvr cClr = ColorBvr.newUninitBvr();
  202.     ImageBvr blockImg = solidColorImage(cClr).
  203.       crop(point2(neg(halfDimNum), neg(halfDimNum)), point2(halfDimNum, halfDimNum));
  204.         
  205.     _dragImg = new DraggableImage(blockImg, initPt2);     
  206.  
  207.     cClr.init(until(red, _dragImg.getGrabEvent(), 
  208.                until(green, _dragImg.getReleaseEvent(), cClr))); 
  209.   }
  210.   
  211.   public ImageBvr getImageBvr() { return _dragImg.getImageBvr(); }
  212.   public Point2Bvr getPointBvr() { return _dragImg.getPointBvr(); }
  213.   DraggableImage _dragImg;  
  214. }
  215.  
  216. // </Tutorial>