Path around a perimeter

hi, i found some old code already posted here at forum
but give it some new show…
i not try to understand the math, just translated it into processing…

it is a math for a OUTER HULL,
not your OUTER LINE concept,
but possibly can be used,
as it fits your question too: “around a perimeter”

// https://www.geeksforgeeks.org/convex-hull-set-1-jarviss-algorithm-or-wrapping/

// Java program to find convex hull of a set of points. Refer 
// https://www.geeksforgeeks.org/orientation-3-ordered-points/ 
// for explanation of orientation() 
import java.util.*; 

GFG myset;

class Point 
{ 
  int x, y; 
  Point(int x, int y){ 
    this.x=x; 
    this.y=y; 
  } 
} 

class GFG { 
  
  // To find orientation of ordered triplet (p, q, r). 
  // The function returns following values 
  // 0 --> p, q and r are colinear 
  // 1 --> Clockwise 
  // 2 --> Counterclockwise 
  public int orientation(Point p, Point q, Point r) 
  { 
    int val = (q.y - p.y) * (r.x - q.x) - 
        (q.x - p.x) * (r.y - q.y); 
  
    if (val == 0) return 0; // collinear 
    return (val > 0)? 1: 2; // clock or counterclock wise 
  } 
  
  // Prints convex hull of a set of n points. 
  public void convexHull(Point points[], int n) 
  { 
    // There must be at least 3 points 
    if (n < 3) return; 
  
    // Initialize Result 
    //Vector<Point> hull = new Vector<Point>(); 
  
    // Find the leftmost point 
    int l = 0; 
    for (int i = 1; i < n; i++) 
      if (points[i].x < points[l].x) 
        l = i; 
  
    // Start from leftmost point, keep moving 
    // counterclockwise until reach the start point 
    // again. This loop runs O(h) times where h is 
    // number of points in result or output. 
    int p = l, q; 
    do
    { 
      // Add current point to result 
      hull.add(points[p]); 
  
      // Search for a point 'q' such that 
      // orientation(p, x, q) is counterclockwise 
      // for all points 'x'. The idea is to keep 
      // track of last visited most counterclock- 
      // wise point in q. If any point 'i' is more 
      // counterclock-wise than q, then update q. 
      q = (p + 1) % n; 
      
      for (int i = 0; i < n; i++)  { 
      // If i is more counterclockwise than 
      // current q, then update q 
      if (orientation(points[p], points[i], points[q]) 
                        == 2) 
        q = i; 
      } 
  
      // Now q is the most counterclockwise with 
      // respect to p. Set p as q for next iteration, 
      // so that q is added to result 'hull' 
      p = q; 
  
    } while (p != l); // While we don't come to first  // point 
    
    // Print Result 
    for (Point temp : hull) 
      println("(" + temp.x + ", " + temp.y + ")"); 
  } 
  
/* Driver program to test above function */
public void make() {

    points[0]=new Point(0, 3); 
    points[1]=new Point(2, 2); 
    points[2]=new Point(1, 1); 
    points[3]=new Point(2, 1); 
    points[4]=new Point(3, 0); 
    points[5]=new Point(0, 0); 
    points[6]=new Point(3, 3); 
    points[7]=new Point(4, 4); 
}

public void hull() {
    int n = points.length; 
    convexHull(points, n); 
  } 
  
} 
  
// This code is contributed by Arnav Kr. Mandal. 
// mod processing KLL

Point[] points = new Point[8]; 
Vector<Point> hull = new Vector<Point>(); 

float zoom=100;

void setup(){
 size(500,500);
 myset = new GFG();
 myset.make();
 myset.hull();
}

void draw() {
  background(200,200,0);
//  translate(width/2,height/2);
  translate(20,20);
  // points
  noStroke();
  fill(200,0,0);
  for ( int i = 0; i<points.length; i++) circle(points[i].x*zoom,points[i].y*zoom,5);
  // result
  stroke(0,200,0);
  noFill();
  int segs = hull.size(); 
  for ( int i = 0; i<segs; i++)   circle(hull.get(i).x*zoom,hull.get(i).y*zoom,7);
  for ( int i = 0; i<segs; i++) {
    float x1 = hull.get(i).x*zoom;
    float y1 = hull.get(i).y*zoom;
    int j = i+1;
    if ( j == segs ) j = 0;
    float x2 = hull.get(j).x*zoom;
    float y2 = hull.get(j).y*zoom;    
    line(x1,y1,x2,y2);
  }

}

1 Like