How can I build Processing code into java libraries?

Hi all,

I am having a starting problem. I don't know how I can integrate java files and classes in my processing code. Can anybody tell me how to do it, such that I can build my own library? Or alternatively, can you point me out to a tutorial that clearly describes it?

In the code that is supplied (see below), I call in the draw()-function two other functions: calculateClosestPoint() and displayInfo(). In the function Mousepressed() I call the functio n saveDepthMap().

I would like to have all three functions - calculateClosestPoint(), displayInfo() and saveDepthMap() - as java classes in a library such that I can reuse them in different processing sketches. I have looked around but I have not been able to find an explanation that was clear to me.

From what I have read, it should be rather straight forward, but have not been able yet to get it working. I would really appreciate some help. I am familiar with eclipse and I am at beginners level in java. I have reasonable experience in programming c++.

Thank you very much in advance.

/*************************************************************************
DESCRIPTION : Test voor het werken met Kinect Depth maps
              Code based on samples from "Making things see"
VERSION     : 150408
***************************************************************************/
import SimpleOpenNI.*;
SimpleOpenNI asus;

//=========================================
// Global variables
//=========================================

// Variables for user enabled choices
//-----------------------------------

// Variables for fileHandling
String gDepthMapDir = "D:/Alldata/Programmeren/Processing_Coding/Sketches_PME/PME/PME_ToProcessingForum_150415/Data/";
String gFileName    = "";
String gFileExt     = ".xyz";
String gFileTextSep = " ";

// Variables for informing the user
boolean dispFramerateInfo  = true;
boolean dispCornerInfo     = true;
boolean dispClosestPoint   = true;

// Variables for showing displays
boolean gMirrorImg          = true;
int     gFramerate          = 10;
boolean dispRGB             = true;

// Variables for calculations
//---------------------------

// Tracking variables for depth
int   closestValue;
int   closestX;
int   closestY;

// Variables for averaging closest point depths
int   n = 5;
int[] recentXvalues = new int[n];
int[] recentYvalues = new int[n];
int   ctrAvg = 0;
int   sumXvalues = 0;
int   sumYvalues = 0;

// Variables for handling the image
int     imageWidth  = 640;
int     imageHeight = 480;
int[]   depthValues = new int[imageWidth * imageHeight];
PImage  rgbImage;

// Variables for storing files
String  gDateTimeStart;                    // Start time of the program


//=========================================
// setup() & draw()
//=========================================
void setup()
{
    // Register the time that the program was started
    gDateTimeStart = 
      str(year())  + nf(month(),2)  + nf(day(),2) + "_" +
              nf(hour(),2) + nf(minute(),2) + nf(second(),2);


    size(imageWidth, imageHeight,OPENGL);
    frameRate(gFramerate);                    // Set frameRate to xx fps

    asus = new SimpleOpenNI(this);
    asus.enableDepth();

    //if (dispRGB == true)     size(imageWidth*2, imageHeight,OPENGL); 
    if (dispRGB == true)     asus.enableRGB();
    if (gMirrorImg == true)  asus.setMirror(true);

}   // <EOR> setup()

void draw()
{
  // Get the depth image
  //-------------------------
  asus.update();
  depthValues = asus.depthMap();
  PImage depthImage = asus.depthImage();
  image(depthImage, 0, 0);
  if (dispRGB == true)
  {
    rgbImage = asus.rgbImage();
    //image(rgbImage, imageWidth,0);
  }

  // Calculate closest point
  //------------------------
  calculateClosestPoint();

  // Inform the user
  //----------------
  displayInfo();


}  // <EOR> draw()

//================================================
// Userdefined functions
//================================================
void mousePressed()
{
  int[] depthValues = asus.depthMap();
  int clickPosition = mouseX + mouseY*640;
  int clickDepth = depthValues[clickPosition];

  if (mouseButton == RIGHT)
  // Save the depthimage to a file
  {
    saveDepthMap();
  }  //  if (mouseButton == RIGHT)
  else
  {
    float cm     = clickDepth /10.0;
    println (mouseX+","+mouseY+ "\tAfstand = " + cm);
  }

}  // <EOF> mousPressed()


/*************************************************************************
FUNCTION    : displayInfo()
DESCRIPTION : Displays user required information in the kinect image
VERSION     : jjmmdd
MODS        : PME150704  : Initial code
***************************************************************************/
void displayInfo()
{
  // Variables for corner information
  int cornerDV     = 0;      // Element number for the element in the  
  int distFromSide = 10;    // Distance from the side of the image
  int cornerX;
  int cornerY;
  // Coordinates of ulc for placing framerate info 
  int framerateinfoX = 0;
  int framerateinfoY = imageHeight / 2;
  // Coordinates of mrs (middel right side) of tracking infromation. 
  int trackX = imageWidth;
  int trackY = imageHeight / 2; 

  // Display closest point  information
  //-----------------------------------
  if (dispClosestPoint == true)
  {
    // Draw a red circle over the closest point
    fill (255,0,0);
    ellipse (closestX, closestY, 3, 3);

    // Place a text, showing the measured distance
    // including the coordinates at which it was measured.
    textAlign(CENTER,BASELINE);
    textSize (20);
    text(str(closestValue), closestX, closestY);

    // Let the user know where the closest point is
    //fill (255,255,128);
    textSize (15);
    textAlign(RIGHT,CENTER);
    text("(" + str(closestX)+"," + str(closestY)+")", trackX,trackY);
    // textAlign(CENTER,TOP);
    //text("(" + str(closestX)+"," + str(closestY)+")", closestX,closestY);
  }  // if (dispClosestPoint == true)

  // Display corner information
  //---------------------------
  if (dispCornerInfo == true)
  {
    fill (55,55,255);

    // Upper Left Corner
    cornerX = 0 + distFromSide;
    cornerY = 0 + distFromSide;
    cornerDV = cornerX + (cornerY * imageWidth);
    textAlign (LEFT,TOP);
    textSize(15);
    ellipse (cornerX,cornerY, 5,5);
    text(str(depthValues[cornerDV]), cornerX,cornerY);

    // Upper Right Corner
    cornerX = imageWidth - distFromSide;
    cornerY = 0 + distFromSide;
    cornerDV = cornerX + (cornerY * imageWidth);
    textAlign (RIGHT,TOP);
    textSize(15);
    ellipse (cornerX,cornerY, 5,5);
    text(str(depthValues[cornerDV]), cornerX,cornerY);

    // Lower Left Corner
    cornerX = 0 + distFromSide;
    cornerY = imageHeight - distFromSide;
    cornerDV = cornerX + (cornerY * imageWidth);
    textAlign (LEFT,BOTTOM);
    textSize(15);
    ellipse (cornerX,cornerY, 5,5);
    text(str(depthValues[cornerDV]), cornerX,cornerY);

    // Lower Right Corner
    cornerX = imageWidth  - distFromSide;
    cornerY = imageHeight - distFromSide;
    cornerDV = cornerX + (cornerY * imageWidth);
    textAlign (RIGHT,BOTTOM);
    textSize(15);
    ellipse (cornerX,cornerY, 5,5);
    text(str(depthValues[cornerDV]), cornerX,cornerY);
  } // if (dispCornerInfo == true)

  // Display Framerate information
  //------------------------------
  if (dispFramerateInfo  == true)
  {
    fill (255,255,128);
    // Place the framerate
    textAlign(LEFT,TOP);
    text("Framerate = " + str(round(frameRate)), framerateinfoX,framerateinfoY);
    text("\n#Frames   = " + str(round(frameCount)), framerateinfoX,framerateinfoY);
  }  //  if (dispFramerateInfo  == true)

}  //  <EOR> displayInfo()


/*************************************************************************
FUNCTION    : saveDepthMap()
DESCRIPTION : Displays user required information in the kinect image
VERSION     : jjmmdd
***************************************************************************/
void saveDepthMap()
{
  String thisFUNCTION = "saveDepthMap()"; 

  int        startMillis = millis();
  int        n  = (imageWidth) * (imageHeight);
  String[]   data = new String[n];
  String     timestamp;
  String     fileName;

  timestamp = gDateTimeStart + "+" + str(millis());

  for (int y = 0; y < imageHeight; y++ ) 
  {
    for (int x = 0; x < imageWidth; x++)
    {
      int ctr = x + y * imageWidth;  // Columnwise accessing of the array.
      data[ctr] = str(x) + gFileTextSep +                    // X
                  str(y) + gFileTextSep +                    // Y
                  str(depthValues[ctr]);
    }
  }

  // Save to File
  // The same file is overwritten by adding the data folder path to saveStrings().
  if (gFileName == "") 
  {
    fileName = timestamp;
  }
  else 
  { 
    fileName = gFileName;
  }


  if (gDepthMapDir != "")
  {
    saveStrings(gDepthMapDir + fileName + gFileExt, data);
  }
  else
  {
    saveStrings("data/" + fileName + gFileExt, data);
  }

  // Finalise function
  //----------------------------------
  println (thisFUNCTION + "-> Processing time = " + (millis() - startMillis) + "ms");

}  //  void saveDepthMap()



/*************************************************************************
FUNCTION    : calculateClosestPoint()
DESCRIPTION : Calculate the closest point in the depthimage
VERSION     : jjmmdd
***************************************************************************/
void calculateClosestPoint()
{
  // Prelimnary calculations
  closestValue = 8000;


  // Start calculation closete point
  //--------------------------------
  for (int y=0; y<imageHeight; y++)
  {
    for (int x=0; x<imageWidth; x++)
    {
      int i = x + (y*imageWidth);
      int currDepthValue = depthValues[i];
      if ((currDepthValue > 0) && (currDepthValue < closestValue))
      { 

        // Set the closest depth value
        closestValue = currDepthValue;
        closestX = x;
        closestY = y;

        // Update the averaging array
        recentXvalues[ctrAvg] = x;
        recentYvalues[ctrAvg] = y;
      } 
    }
  }  //  for (int y=0; y<imageHeight; y++)

  // Calculate the average position 
  ctrAvg++;
  if (ctrAvg > (n-1)) ctrAvg = 0; 

  sumXvalues = 0;
  sumYvalues = 0;
  for (int ctr=0; ctr<n; ctr++)
  {
    sumXvalues += recentXvalues[ctr]; 
    sumYvalues += recentYvalues[ctr]; 
  }
  closestX = sumXvalues / n;
  closestY = sumYvalues / n;
}  //  <EOF> calulateCLosestPoint()

Answers

  • edited April 2015

    IMO all of those 3 methods, calculateClosestPoint(), displayInfo(), saveDepthMap(), are unfit for a separate class, much less belong to their own library!
    At most they coulda be saved as snippets in some file and copy'n'pasted in sketches that need'em.

    Now the harder part, explaining the reasons why:

    • Processing framework, in its most basic form, is the PApplet class plus a drawing canvas.
    • Functions setup(), draw(), mousePressed(), etc. are callbacks for its "Animation" Thread.
    • The "sketch" itself extends PApplet and it's a full Java class instance.
    • In order to access the canvas, we need that instance's reference/pointer.
    • Therefore, in order for a library or some other top class to be able to draw anything, it gotta request that reference.

    Basically, the problem w/ your 3 functions is how much they are bound to the sketch's instance.

    For instance, calculateClosestPoint() directly reads and writes sketch's fields like closestValue, imageHeight, recentXvalues, etc.
    In short, it acts upon the sketch's data and should stay as it is now as a sketch's method.

    And displayInfo() & saveDepthMap() go even further in how much they depend on the sketch's state.
    Besides having the same problem about depending on the sketch's fields, they also call stateful Processing's API methods.

    Anything which acts upon the sketch's canvas or needs to know its folder path demands the sketch's reference if they belong to another external class or library!

    Well, any further doubts just ask here again! B-)

  • Hi GoToLoop,

    Thanks for the reply. It makes a lot of sense and it is just the dependency on the sketch that I want to remove. Also, I do not like the extensive use of the global variables as shown in the example. Therefore I am now re-wrting the methods calculateClosestPoint(), displayInfo() and saveDepthMap() into a java class such that these can take arguments. By doing this I remove the dependencies from the sketch and disconnect calculation from the user interface.

    When I have finished re-wrting, I will be in a better position to create a library from the classes and I will ask teh question again.

    Anyway, thanks a lot. You pointed me in a good direction.

  • So now I rewrote the code to replace calculateClosestPoint(), displayInfo() and saveDepthMap with two classes: CanvasUpdater{} and CalculationManager{}. The CanvasUpdater takes care of the placing user defined texts on the canvas and the CalculationManager takes care of the calculations. See the code below.

    I think I have separated them from the sketch now in the sense that these do not act on the sketch's data anymore. As such they may be candidates to be included in a library.

    Now suppose I want to plut them in a library called "myCanvasHandler", how should I proceed? Could anyone point me in the right direction (an explanation in this forum or a link to a tutorial etc).

    And if that is still not possible, what is the next best option? I guess it is placing them as snippets in some file (as described earlier), but that leaves me with the questions: where to place that file and how do I include that file in my main sketch?

    Thanks in advace for your feedback.

    /*************************************************************************
    DESCRIPTION : Test voor het werken met Kinect Depth maps
                  Code based on samples from "Making things see"
    VERSION     : 150408
    ***************************************************************************/
    import SimpleOpenNI.*;
    SimpleOpenNI asus;
    
    
    //=========================================
    // Global variables
    //=========================================
    
    //------------------------------------------------------
    // Variables for user enabled choices
    //------------------------------------------------------
    
    // Variables for fileHandling
    String gDepthMapDir = "D:/Alldata/Programmeren/Processing_Coding/Sketches_PME/PME/PME_ToProcessingForum_150415/Data/";
    String gFileName    = "";
    String gFileExt     = ".xyz";
    String gFileTextSep = " ";
    
    // Variables for informing the user
    boolean dispFramerateInfo  = true;
    boolean dispCornerInfo     = true;
    boolean dispClosestPoint   = true;
    boolean trckClosestPoint   = true;
    
    // Variables for showing displays
    boolean gMirrorImg          = true;
    int     gFramerate          = 15;
    boolean dispRGB             = true;
    
    //------------------------------------------------------
    // Variables for calculations
    //------------------------------------------------------
    
    // Tracking variables for depth
    int   gClosestValue;
    int   gClosestX;
    int   gClosestY;
    
    // Variables for averaging closest point depths
    PVector             myClosestPoint;
    ArrayList<PVector>  closestPoints = new ArrayList<PVector>();
    int                 gMaxPointsToAverage = 3; 
    int                 pointCtr = 0;
    
    // Variables for handling the image
    int     imageWidth  = 640;
    int     imageHeight = 480;
    int[]   depthValues = new int[imageWidth * imageHeight];
    PImage  rgbImage;
    
    // Variables administration of actions.
    String   gDateTimeStart;                    // Start time of the program
    int      curMillis;
    int      prevMillis;
    
    // Classes (possible candidates for libraries?)
    CanvasUpdater       myCanvasUpdater  = new CanvasUpdater(imageWidth,imageHeight);
    CalculationManager  calcMgr          = new CalculationManager();
    
    //==========================================================
    // setup() & draw()
    //==========================================================
    void setup()
    {
        // Initialize administration variables
        //------------------------------------
        // Set time that the program was started
        gDateTimeStart = str(year())  + nf(month(),2)  + nf(day(),2) + "_" +
                         nf(hour(),2) + nf(minute(),2) + nf(second(),2);
    
        // Timing for the draw()-method
        prevMillis  = 0;
        curMillis   = 0;
    
        // Initialize image and canvas variables
        //--------------------------------------
        size(imageWidth, imageHeight,OPENGL);
        frameRate(gFramerate);                    // Set frameRate to xx fps
    
        asus = new SimpleOpenNI(this);
        asus.enableDepth();
    
        //if (dispRGB == true)     size(imageWidth*2, imageHeight,OPENGL); 
        if (dispRGB == true)     asus.enableRGB();
        if (gMirrorImg == true)  asus.setMirror(true);
    
    }   // <EOR> setup()
    
    void draw()
    {
      prevMillis = curMillis;
    
      // Get the depth image
      //-------------------------
      asus.update();
      depthValues = asus.depthMap();
      PImage depthImage = asus.depthImage();
      image(depthImage, 0, 0);
      if (dispRGB == true)
      {
        rgbImage = asus.rgbImage();
        //image(rgbImage, imageWidth,0);
      }
    
      // Calculate closest point
      //------------------------
    
      myClosestPoint =  calcMgr.calculateClosestPoint(depthValues, imageWidth, imageHeight);
      closestPoints.add(myClosestPoint);
      pointCtr++;
      //DEBUGGING
      //println("PointCtr = "+pointCtr + ",\t" + myClosestPoint.x + ",\t" + myClosestPoint.y + ",\t" + myClosestPoint.z);
    
      if (pointCtr >= gMaxPointsToAverage)
      {
        PVector avgPt = calcMgr.averagePoints(closestPoints);
        closestPoints.clear();
        pointCtr = 0;
    
        //DEBUGGING
        //println ("avgPt = " + avgPt.x + ",\t" + avgPt.y + ",\t" + avgPt.z + ",\t"); 
    
        gClosestX      = (int) avgPt.x;
        gClosestY      = (int) avgPt.y;
        gClosestValue  = (int) avgPt.z;
      }
    
      // Inform the user
      //----------------
      //displayInfo();
      if (dispFramerateInfo  == true) { myCanvasUpdater.displayFrameInfo     (0, imageHeight/2); }
      if (dispCornerInfo     == true) { myCanvasUpdater.displayCornerInfo    (depthValues); }
      if (dispClosestPoint   == true) { myCanvasUpdater.displayClosestPoint  (gClosestValue, gClosestX, gClosestY, imageWidth, imageHeight/2); }
      if (trckClosestPoint   == true) { myCanvasUpdater.trackClosestPoint    (gClosestValue, gClosestX, gClosestY); }
    
      // Measure timing for the method
      curMillis = millis();
      println ("Cycle time draw() = " + (curMillis - prevMillis) + " ms");
    }  // <EOR> draw()
    
    //================================================
    // Userdefined functions
    //================================================
    void mousePressed()
    {
      int[] depthValues = asus.depthMap();
      int clickPosition = mouseX + mouseY*640;
      int clickDepth = depthValues[clickPosition];
    
      if (mouseButton == RIGHT)
      // Save the depthimage to a file
      {
        String timestamp = gDateTimeStart + "+" + str(millis());
        calcMgr.saveDepthMap(depthValues, imageWidth, imageHeight, timestamp,
                             gFileName, gFileExt, gFileTextSep, gDepthMapDir);
    //    saveDepthMap();
      }  //  if (mouseButton == RIGHT)
      else
      {
        float cm     = clickDepth /10.0;
        println (mouseX+","+mouseY+ "\tAfstand = " + cm);
      }
    
    }  // <EOF> mousPressed()
    
    
    //****************************************************
    //***** CLASS DEFINITIONS ****************************
    //****************************************************
    
    /***********************************************************************************
    CLASS       : CalculationManager{}
    DESCRIPTION : Manages the required calculations
    VERSION     : jjmmdd
    ************************************************************************************/
    public class CalculationManager 
    {
      String mCLASSNAME = "CalculationManager";
    
    
      // Constructor
      public CalculationManager()  {  }
    
      /*************************************************************************
      METHOD      : calculateClosestPoint()
      DESCRIPTION : Calculate the closest point in the canvas of the depthimage
      VERSION     : jjmmdd
      ***************************************************************************/
      public PVector calculateClosestPoint(int[] dvCanvas, int canvasWidth, int canvasHeight)
      {
        // Declare variables
        //------------------
        PVector  myVector = new PVector(0,0,0);
        int x=0;
        int y=0;
        int closestValue = 8000;
    
        // Start calculation closest point
        //--------------------------------
        for (int yctr=0; yctr<canvasHeight; yctr++)
        {
          for (int xctr=0; xctr<canvasWidth; xctr++)
          {
            int i = xctr + (yctr*canvasWidth);
            int currDepthValue = dvCanvas[i];
            if ((currDepthValue > 0) && (currDepthValue < closestValue))
            { 
              // Set the closest depth value
              closestValue = currDepthValue;
              x = xctr;
              y = yctr;
            } 
          }
        }  //  for (int yctr=0; yctr<imageHeight; yctr++)
        myVector.x = x;
        myVector.y = y;
        myVector.z = closestValue;
    
        // Return from method
        //-------------------
        return myVector;
      }  //  <EOM> calculateClosestPoint()
    
    
      /*************************************************************************
      METHOD      : averagePoints()
      DESCRIPTION : Averages the point in the ArrayList pointList
      VERSION     : jjmmdd
      ***************************************************************************/
      public PVector averagePoints(ArrayList<PVector> pointList)
      {
        // Define local variables
        //-----------------------
        String    FUNCNAME  = mCLASSNAME + "::" + "averagePoints()";
        PVector   result    = new PVector();
        int       sumX      = 0;
        int       sumY      = 0;
        int       sumZ      = 0;
        int       n         = pointList.size();
    
    
        // Check Pre-conditions
        //---------------------
    
        // n>0
        if (n<=0) {
          println ("!!! ERROR !!!  " + FUNCNAME + "-> No valid number of elements in pointList.");
          return result;
        }
    
        // Start Calculation
        //------------------
        for (int i=0; i<pointList.size(); i++)
        {
          sumX += pointList.get(i).x; 
          sumY += pointList.get(i).y; 
          sumZ += pointList.get(i).z; 
        }
        result.x = sumX / n;
        result.y = sumY / n;
        result.z = sumZ / n;
    
        // Return from method
        //-------------------
        return result;
      }  // <EOM> averagePoints()
    
    
      /*************************************************************************
      FUNCTION    : saveDepthMap()
      DESCRIPTION : Saves a depthmap acquired by the kinect
      VERSION     : jjmmdd
      ***************************************************************************/
      void saveDepthMap(int[] dmValues, int dmWidth, int dmHeight, String timestamp, 
                        String fileName, String fileExt, String fileSep, String filePath)
      {
        // Declare variables
        //------------------
        String FUNCNAME = mCLASSNAME + "::saveDepthMap()"; 
    
        int        startMillis = millis();
        int        n  = (dmWidth) * (dmHeight);
        String[]   data = new String[n];
        //String     timestamp;
        //String     fileName;
    
        // Start Calculation
        //------------------
    
        // timestamp = gDateTimeStart + "+" + str(millis());
    
        for (int y = 0; y < dmHeight; y++ ) 
        {
          for (int x = 0; x < dmWidth; x++)
          {
            int ctr = x + y * dmWidth;  // Columnwise accessing of the array.
            data[ctr] = str(x) + gFileTextSep +                    // X
                        str(y) + gFileTextSep +                    // Y
                        str(dmValues[ctr]);
          }
        }
    
        // Save to File
        // The same file is overwritten by adding the data folder path to saveStrings().
        if (gFileName == "") 
        {
          fileName = timestamp;
        }
        else 
        { 
          fileName = gFileName;
        }
    
        if (gDepthMapDir != "")
        {
          saveStrings(gDepthMapDir + fileName + gFileExt, data);
        }
        else
        {
          saveStrings("data/" + fileName + gFileExt, data);
        }
    
        // Return from function
        //---------------------
        println (FUNCNAME + "-> Processing time = " + (millis() - startMillis) + "ms");
      }  //  void saveDepthMap()
    
    }  // <EOC< CalculationManager{}
    
    
    /***********************************************************************************
    CLASS       : CanvasUpdater{}
    DESCRIPTION : Contains all required functionality to update the canvas
    VERSION     : jjmmdd
    ************************************************************************************/
    public class CanvasUpdater 
    {
      int mWidth;
      int mHeight;
    
      // Constructor
      public CanvasUpdater(int canvasWidth, int canvasHeight)
      {
        mWidth = canvasWidth;
        mHeight = canvasHeight;
      }  //  <EOM> CanvasUpdater()
    
    
      /***********************************************************************************
      METHOD      : CanvasUpdater::displayFrameInfo()
      DESCRIPTION : Displays framerate and unmber of frames processed.
      VARIABLES   : x,y  :  IN  :  locatio on the for the info t be displayed.
      VERSION     : jjmmdd
      ************************************************************************************/
      public void  displayFrameInfo (int x, int y)
      {
        fill (255,255,128);
        // Place the framerate
        textAlign(LEFT,TOP);
        text("Framerate = "   + str(round(frameRate)),  x,y);
        text("\n#Frames   = " + str(round(frameCount)), x,y);
      } // displayFrameInfo ()
    
    
      /***********************************************************************************
      METHOD      : CanvasUpdater::displayCornerInfo()
      DESCRIPTION : Displays in the corners of the depthmap the values that are measured.
      VARIABLES   : dvCanvas : IN : canvas (array) holding the depthmap.
      VERSION     : jjmmdd
      ************************************************************************************/
      public void displayCornerInfo (int[] dvCanvas)
      {
        //---------------------
        // Variable declaration
        //---------------------
        int cornerDV     = 0;      // Element number for the element in the  
        int distFromSide = 10;    // Distance from the side of the image
        int cornerX;
        int cornerY;
    
        //------------------
        // Start Calculation
        //------------------
        fill (55,55,255);
    
        // Upper Left Corner
        cornerX = 0 + distFromSide;
        cornerY = 0 + distFromSide;
        cornerDV = cornerX + (cornerY * imageWidth);
        textAlign (LEFT,TOP);
        textSize(15);
        ellipse (cornerX,cornerY, 5,5);
        text(str(dvCanvas[cornerDV]), cornerX,cornerY);
    
        // Upper Right Corner
        cornerX = imageWidth - distFromSide;
        cornerY = 0 + distFromSide;
        cornerDV = cornerX + (cornerY * imageWidth);
        textAlign (RIGHT,TOP);
        textSize(15);
        ellipse (cornerX,cornerY, 5,5);
        text(str(dvCanvas[cornerDV]), cornerX,cornerY);
    
        // Lower Left Corner
        cornerX = 0 + distFromSide;
        cornerY = imageHeight - distFromSide;
        cornerDV = cornerX + (cornerY * imageWidth);
        textAlign (LEFT,BOTTOM);
        textSize(15);
        ellipse (cornerX,cornerY, 5,5);
        text(str(dvCanvas[cornerDV]), cornerX,cornerY);
    
        // Lower Right Corner
        cornerX = imageWidth  - distFromSide;
        cornerY = imageHeight - distFromSide;
        cornerDV = cornerX + (cornerY * imageWidth);
        textAlign (RIGHT,BOTTOM);
        textSize(15);
        ellipse (cornerX,cornerY, 5,5);
        text(str(dvCanvas[cornerDV]), cornerX,cornerY);
      }  // <EOM> displayCornerInfo()
    
    
      /***********************************************************************************
      METHOD      : CanvasUpdater::displayClosestPoint()
      DESCRIPTION : Displays the values for the closest point.
      VARIABLES   : distance            : IN  : distance measured at the location of the closest point
                    xDist,yDist         : IN  : location wher closes distance was measured.
                    xDisplay, yDisplay  : IN  : Location where info has to be displayed.
      VERSION     : jjmmdd
      ************************************************************************************/
      public void displayClosestPoint  (int distance, int xDist, int yDist, int xDisplay, int yDisplay)
      {
        fill (255,0,0);
        textSize (15);
        textAlign(RIGHT,CENTER);
        text("(" + str(xDist)+"," + str(yDist)+")", xDisplay,yDisplay);
      }  // <EOM> displayClosestPoint()
    
      /***********************************************************************************
      METHOD      : CanvasUpdater::trackClosestPoint()
      DESCRIPTION : Displays the values for the closest point.
      VARIABLES   : distance            : IN  : distance measured at the location of the closest point
                    xDist,yDist         : IN  : location wher closes distance was measured.
                    xDisplay, yDisplay  : IN  : Location where info has to be displayed.
      VERSION     : jjmmdd
      ************************************************************************************/
      public void trackClosestPoint (int value, int x, int y)
      {
        // Draw a red circle over the closest point
        fill (255,0,0);
        ellipse (x, y, 3, 3);
    
        // Place a text, showing the measured distance
        // including the coordinates at which it was measured.
        textAlign(CENTER,BASELINE);
        textSize (20);
        text(str(value), x, y);
      }  //  <EOM> trackClosestPoint()
    
    }  // <EOC> CanvasUpdater{}
    
Sign In or Register to comment.