Advertisement
StarShadow

Inverse Kinematics

Jun 26th, 2018
163
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 2.31 KB | None | 0 0
  1. import java.util.List;
  2.  
  3. // Class to calculate inverse kinematics
  4. public class InvKin {
  5.    
  6.     private double[] lengths;
  7.     private List<Point> points;
  8.     private Point start;
  9.     private Point target;
  10.    
  11.     public InvKin(List<Point> points, Point target) {
  12.         if (points.size() < 2) throw new IllegalArgumentException("Not enough points for inverse kinematics");
  13.         this.start = points.get(0).copy();
  14.         this.points = points;
  15.         this.target = target;
  16.         //
  17.         lengths = new double[points.size() - 1];
  18.         for (int i = 0; i < lengths.length; i++) {
  19.             lengths[i] = points.get(i).distance(points.get(i + 1));
  20.         }
  21.     }
  22.    
  23.     private void backwards() {
  24.         int last = points.size() - 1;
  25.         points.get(last).set(target);
  26.         for (int i = points.size() - 2; i >= 0; i--) {
  27.             Point c = points.get(i);
  28.             Point n = points.get(i + 1);
  29.             c.set(n.getPoint(n.angleTo(c), lengths[i]));
  30.         }
  31.     }
  32.    
  33.     private void forwards() {
  34.         int first = 0;
  35.         points.get(first).set(start);
  36.         for (int i = 1; i < points.size(); i++) {
  37.             Point c = points.get(i);
  38.             Point p = points.get(i - 1);
  39.             c.set(p.getPoint(p.angleTo(c), lengths[i - 1]));
  40.         }
  41.     }
  42.    
  43.     private void iterate() {
  44.         backwards();
  45.         forwards();
  46.     }
  47.    
  48.     // Calculate new positions within the error bound.
  49.     public void calculate(double err) {
  50.         int total = 0;
  51.         for (double length : lengths) {
  52.             total += length;
  53.         }
  54.         if (start.distance(target) > total) { // Chain isn't long enough to connect
  55.             for (int i = 1; i < points.size(); i++) {
  56.                 Point c = points.get(i);
  57.                 Point p = points.get(i - 1);
  58.                 c.set(p.getPoint(p.angleTo(target), lengths[i - 1]));
  59.             }
  60.             return;
  61.         }
  62.         int last = points.size() - 1;
  63.         double error = points.get(last).distance(target);
  64.         double l = -1;
  65.         while (error > err) {
  66.             iterate();
  67.             error = points.get(last).distance(target);
  68.             if (l == error) break;
  69.             l = error;
  70.         }
  71.     }
  72.    
  73.     public List<Point> getPoints() {
  74.         return points;
  75.     }
  76.    
  77. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement