SDO_DISTANCE - is it Euclidean distance?

1. I have geodetic location data in a spatial object (X,Y,Z) as 3-dim points. When I use the SDO_DISTANCE function, is it returning the Euclidean distance between the two 3-dim points (considering all 3 dimensions)?
2. Is there a way to use SDO_DISTANCE to return the distance between the points in each of the 3 dimensions?
Thanks,
Julien

Hi Julian,
Nearly all spatial operators and functions work only on two dimensions.
If the data was projected then the linear referencing package can work in three dimensions, however that is only for projected data and only works for distances along a single linear feature. Long/lat data (geodetic) is currently only supported in "two" dimensions.
I put the "two" in quotes above, because support for Long/Lat distances is non-Euclidean in spatial. If the data is recognized as geodetic (geodetic SDO_SRID value) then ellipsoidal distances are used.
Hope this helps, but the answers to 1 and 2 are no.

Similar Messages

  • Scalar distance across columns

    I need to calculate the scalar (Euclidean) distance between two vectors, each dimension represented by columns in a table. I have a procedure that does it the slow and painful way: loop over all vector pairs/loop over all columns/look up the individual cell values/sum over all the differences. It appears to me though, that there should be a more straightforward way to do this using the:
    SELECT * FROM TST INTO vREF_DATA WHERE REGNO=1;
    SELECT * FROM TST INTO vCMP_DATA WHERE REGNO=2;
    syntax in PL/SQL, then loop over the variables/column elements to sum the differences. However, I can't figure out how to keep the pointers for each variable in sync.
    E.g.: coord1(1,2,3), coord2(2,3,1), differences(1,1,2), sum=4.
    I can do this in Perl using hashes/arrays, but not in PL/SQL. What is the right frame/syntax to do this? If it were a couple of hundred rows, I'd do it in Perl, but with millions of rows and hundreds of columns, it gets real tedious, not to mention easily out-of-sync with the database contents.
    I'd appreciate any suggestions!

    Michiel:
    Glad that it works for you. So, you want a fishing lesson :-).
    First, the full documentation for the DBMS_SQL package can be found here .
    Essentially, DBMS_SQL is an industrial strength version of EXECUTE IMMEDIATE (well, properly, EXECUTE IMMEDIATE is a highly simplified version of DBMS_SQL, since DBMS_SQL came first). It has many advantages over EXECUTE IMMEDIATE because it allows you full control over virtually everything to do with the query. So, you can relatively easily create bind variables on the fly to create statements with an unknown number of binds. It also allows you to find the columns from any arbitrary query through DBMS_SQL.Describe_Columns.
    You never actually see any values returned, because I never actually return any. Since you wanted your output in another table, I decided to build one big insert statement, rather than iterate through all the rows, calculate the distance, and then insert one row at a time. It seemed more efficient to me. I also decided to "hard code", through a bind variable, each of the column values from the ref_id, rather than try to dynamically build a join, which seemd simpler to me.
    1. DBMS_SQL.Describe_Columns returns a table of records, one record for each column, that gives information much like that in the xxx_tab_columns views. If some id columns may be numeric, you can test the col_type field in the table of records and put a dummy VARCHAR variable into the character columns. Just be aware that the col_type field returns a numeric version of the column_type, not a string. If you look at the text from user_tab_cols:
    SELECT text
    FROM dba_views
    WHERE view_name = 'USER_TAB_COLS'You can see where Oracle DECODES the numeric type to the NUMBER, VARCHAR2 etc. Essentially, NUMBER is 1 and VARCHAR2 is 2.
    2. I replaced the FOR scale_rec IN ... LOOP block with another DBMS_SQL built query to pull the AVG and VARIANCE from the table, it is commented in the code below.
    3. You cannot really put a threshold on the computation of the distance, since the distance is not really known to the query until it is fully executed (i.e. at the time of inserting). However, you could modify the insert query to filter values with distances greater than 3. I will leave that modification as a exercise for the fiherman, but the end sql statement would look something like:
    INSERT INTO diag
    SELECT src, id, dist
    FROM (SELECT :src_id src, id,
            SQRT(ABS((POWER((:sc2 - :mean2)/:var2, 2) - POWER((col1 - :mean2)/:var2, 2))+
                     (POWER((:sc3 - :mean3)/:var3, 2) - POWER((col2 - :mean3)/:var3, 2))+
                     (POWER((:sc4 - :mean4)/:var4, 2) - POWER((col3 - :mean4)/:var4, 2)))) dist
          FROM t
          WHERE id <> :src_id)
    WHERE dist <= 3Now here is a heavily commented version taking into account the proper formula.
    CREATE or replace PROCEDURE euclidean_distance (p_src_tab IN VARCHAR2) AS
       -- Associative Array for scaling factors
       TYPE scale_cols_tp IS TABLE OF NUMBER INDEX BY VARCHAR2(30);
       mean_cols scale_cols_tp; -- Will hold average of columns
       var_cols scale_cols_tp;  -- Will hold variance of columns
       -- Array to hold column values for the reference id
       TYPE src_cols_tp IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
       src_cols src_cols_tp;
       l_dummyn NUMBER;  -- Dummy Number for Define Column
       l_ignore NUMBER;  -- Receives rows processed from queries
       l_sqlstr VARCHAR2(32767);  -- For sql statements
       src_cur  NUMBER;  -- Reference ID Cursor handle
       src_tab  DBMS_SQL.Desc_Tab;  -- Table of Records describing passed table
       src_col_cnt NUMBER;   -- Number of columns in passed table
       ins_cur  NUMBER;  -- Insert Cursor handle
       mv_cur  NUMBER;  -- Cursor handle for Mean and Variance of table
       l_col_pos NUMBER; -- Index into src_tab
       l_res_pos NUMBER; -- Column position in mv_cur
       l_x1     VARCHAR2(10);  -- Dynamic bind variable for source column values
       l_x2     VARCHAR2(30);  -- Column name from source columns
       l_meani  VARCHAR2(10);  -- Dynamic bind variable for mean of table
       l_vari   VARCHAR2(10);  -- Dynamic bind variable for variance of table
    BEGIN
       -- Get a "handle" for a cursor, and parse the query
       src_cur := DBMS_SQL.Open_Cursor;
       DBMS_SQL.Parse(src_cur, 'SELECT * FROM '||p_src_tab||' WHERE id = :src_id',DBMS_SQL.Native);
       -- Describe the table to get number of columns, their names and their types
       DBMS_SQL.Describe_Columns(src_cur, src_col_cnt, src_tab);
       -- I now have a table of records (src_tab) showing similar info
       -- to that shown in xxx_tab_columns, one record per column
       -- and the number of columns in the table (actually the number of records
       -- in src_tab) is in src_col_cnt
       -- Define the column types for src_cur.  This just tell DBMS_SQL that
       -- the column at position i (based on the column list in the select)
       -- is of the passed data type.  It is not setting a variable to
       -- receive the column value.
       -- I am assuming all inluding ID are NUMBER.
       -- If id may be alpha can test src_tab(i).col_type to check data type
       FOR i IN 1 .. src_col_cnt LOOP
          DBMS_SQL.DEFINE_COLUMN(src_cur, i, l_dummyn);
       END LOOP;
    -- This section replaces the FOR scale_rec IN LOOP
       -- Get mean and variance for passed table
       -- Build the sql statement
       l_sqlstr := 'SELECT ';
       FOR i IN 2 .. src_col_cnt LOOP
          l_sqlstr := l_sqlstr||'AVG('||src_tab(i).col_name||'),'||
                'VARIANCE('||src_tab(i).col_name||'),';
       END LOOP;
       -- l_sqlstr is now:
       -- SELECT AVG(col1), VARIANCE(col1),AVG(col2), VARIANCE(col2),
       --        AVG(col3), VARIANCE(col3),
       -- So trim the trailing , and add FROM
       l_sqlstr := RTRIM(l_sqlstr,',');
       l_sqlstr := l_sqlstr||' FROM '||p_src_tab;
       -- Set up the cursor
       mv_cur := DBMS_SQL.OPEN_CURSOR;
       DBMS_SQL.Parse(mv_cur, l_sqlstr, DBMS_SQL.Native);
       -- Getting 2 results (AVG and VARIANCE) for each column
       -- and we know that they are all numeric
       -- but need to ignore the id column so
       FOR i In 1 .. (src_col_cnt - 1) * 2 LOOP
          DBMS_SQL.DEFINE_COLUMN(mv_cur, i, l_dummyn);
       END LOOP;
       -- Now Run the query and assign columns into associative array
       l_ignore := DBMS_SQL.EXECUTE_AND_FETCH(mv_cur);
       l_col_pos := 2;  -- start in Record 2 of src_tab
       l_res_pos := 1;  -- start in Column 1 of result set
       WHILE l_col_pos <= src_col_cnt LOOP
          DBMS_SQL.COLUMN_VALUE(mv_cur, l_res_pos, mean_cols(src_tab(l_col_pos).col_name));
          DBMS_SQL.COLUMN_VALUE(mv_cur, l_res_pos + 1, var_cols(src_tab(l_col_pos).col_name));
          l_col_pos := l_col_pos + 1;
          l_res_pos := l_res_pos + 2;
       END LOOP;
       -- I end up with two associative arrays, both indexed by column name
       -- mean_cols values are the average for each column
       -- var_cols values are the variance for each column
       -- We're done with this query so
       DBMS_SQL.Close_Cursor(mv_cur);
    -- END replacement FOR scale_rec IN LOOP
       -- Build the insert statement
       -- I took the ABSolute value of the SUM of L(i) because with
       -- my data I was getting negative values which blew the SQRT
       l_sqlstr := 'INSERT INTO diag SELECT :src_id, id, SQRT(ABS(';
       FOR i IN 2 .. src_col_cnt LOOP
          -- Dynamically create bind variables to hold "fixed" values
          -- (i.e. reference values, mean, and variance
          -- and plug the correct column names for the target columns
          l_x1 := ':sc'||i; -- For i = 2 gives :sc2
          l_x2 := src_tab(i).col_name; -- For i = 2 gives COL1
          l_meani := ':mean'||i; -- For i = 2 gives :mean2
          l_vari := ':var'||i; -- For i = 2 gives :var2
          -- Append this column formula to sql statement
          l_sqlstr := l_sqlstr ||'(POWER(('||l_x1||' - '||l_meani||
                      ')/'||l_vari||', 2) - POWER(('||l_x2||' - '||
                      l_meani||')/'||l_vari||', 2)) + ';
       END LOOP;
       -- Here, l_sqlstr is:
       -- INSERT INTO diag
       -- SELECT :src_id, id, SQRT(ABS((POWER((:sc2 - :mean2)/:var2, 2) -
       --                               POWER((col1 - :mean2)/:var2, 2))+
       --                              (POWER((:sc3 - :mean3)/:var3, 2) -
       --                               POWER((col2 - :mean3)/:var3, 2))+
       --                              (POWER((:sc4 - :mean4)/:var4, 2) -
       --                               POWER((col3 - :mean4)/:var4, 2))+
       -- so get rid of the trailing + and space
       l_sqlstr := RTRIM(l_sqlstr,'+ ');
       -- Now close the open bracket from SQRT and ABS and add FROM and WHERE
       l_sqlstr := l_sqlstr||')) FROM '||p_src_tab||' WHERE id <> :src_id';
       -- Now we have a valid insert statement so
       -- Prepare and parse the insert cursor
       ins_cur := DBMS_SQL.Open_Cursor;
       DBMS_SQL.Parse(ins_cur, l_sqlstr, DBMS_SQL.Native);
       -- bind in the mean and variance which are fixed for this set of columns
       FOR i IN 2 .. src_col_cnt LOOP
          DBMS_SQL.Bind_Variable(ins_cur,':mean'||i, mean_cols(src_tab(i).col_name));
          DBMS_SQL.Bind_Variable(ins_cur,':var'||i, var_cols(src_tab(i).col_name));
          -- for i = 2, These two calls resolve as:
          -- DBMS_SQL.Bind_Variable(ins_cur,:mean2, mean_cols(COL1));
          -- DBMS_SQL.Bind_Variable(ins_cur,:var2, var_cols(COL1));
          -- which means bind the value found in mean_cols('COL1') to
          -- the bind variable :mean2 and the value found in var_cols('COL1') to 
          -- the bind variable :var2
       END LOOP;
       -- Get the reference IDs
       FOR intrest_rec IN (SELECT ref_id FROM query) LOOP
          -- For each reference ID bind into the source query
          DBMS_SQL.Bind_Variable(src_cur,':src_id', intrest_rec.ref_id);
          -- So, here, on the first iteration, we are about to execute
          -- the statement
          -- SELECT * FROM t WHERE id = 1     
          l_ignore := DBMS_SQL.Execute_And_Fetch(src_cur);
          -- Get the column values from each source row and
          -- bind that value (e.g. 1 in my sample) to variable :src_id
          DBMS_SQL.Bind_Variable(ins_cur,':src_id', intrest_rec.ref_id);
          FOR i IN 2 .. src_col_cnt LOOP
             -- Retrieve the value of each column of the source row
             -- into the table of NUMBERS
             DBMS_SQL.COLUMN_VALUE(src_cur, i, src_cols(i));
             -- Then bind it into the insert cursor
             DBMS_SQL.Bind_Variable(ins_cur,':sc'||i, src_cols(i));
          END LOOP;
          -- execute the insert statement
          l_ignore := DBMS_SQL.EXECUTE(ins_cur);
       END LOOP;
       COMMIT;
       DBMS_SQL.Close_Cursor(src_cur);
       DBMS_SQL.Close_Cursor(ins_cur);
    END;If you still have questions, I will be around until Thursday, then back January 4.
    John

  • SDO_LENGTH vs Mapviewer Distance Tool

    Hello All
    we have an issue related with sdo_length function
    Using distance tool i take the length of my lenear geometry , and it shows 62.568 YARD , by using following sdo_length query i got different answer 78.09 .
    select SDO_GEOM.SDO_LENGTH(st.OGC_GEOMETRY, m.diminfo,'unit=YARD') from STRAND st, user_sdo_geom_metadata m where ST.XFM_ID=157146
    is there anything wrong with my spatial query .
    Please help me

    That explains it. 3785 is a projection system. The length result returned by sdo_length is the Euclidean distance in the projection system, which is usually not very accurate. The oracle maps client calculates distance in a more accurate way. It first transforms coordinates in 3785 into lat/lon and then calculates the great earth distance between them. If you do the same with sdo_length, you should get the same result.
    Edited by: Ji Yang on Dec 9, 2010 6:14 AM

  • Finding Distance between two zipcodes with longtitude and latitude

    Want to find distance between two zipcodes that have their latitude and longitude stored in a table.
    The table is as follows
    CREATE TABLE distance (zipcode VARCHAR2, LNG NUMBER, LAT NUMBER)
    I couldn't come up with a calculation or understand the mathematical calculation on line.. Can you help me with some stored procedure that will do..?
    Thanks

    There is no logical complexity in your query besides knowing the basics of
    http://en.wikipedia.org/wiki/Spherical_coordinates
    Also, the table name "Distance" cannot be more confusing; what you have is essentially "PointsOnSphere".
    select R*sqrt(
    (sin(pi-p1.lng)*cos(p1.lat)-sin(pi-p2.lng)*cos(p2.lat))* (sin(pi-p1.lng)*cos(p1.lat)-sin(pi-p2.lng)*cos(p2.lat))
    +
    (sin(pi-p1.lng)*sin(p1.lat)-sin(pi-p2.lng)*sin(p2.lat))*
    (sin(pi-p1.lng)*sin(p1.lat)-sin(pi-p2.lng)*sin(p2.lat))
    +
    (cos(pi-p1.lng)-cos(pi-p2.lng))*(cos(pi-p1.lng)-cos(pi-p2.lng))
    from distance p1, distance p2
    where R is the radius of Earth, and pi=3. Don't forget to convert angular degrees into radiants before you plug in them into the query above
    Correction: This was euclidean distance sqrt((x1-x2)^2+(y1-y2)^2+(z1-z2)^2) between the points (x1,y1,z1) and (x2,y2,z2). Spherical distance is
    sqrt(
    (R*(colatitude1-colatitude2))^2+
    (R*sin(colatitude1-colatitude2)*(longtitude1-longtitude2))^2
    Message was edited by:
    Vadim Tropashko

  • No warning for 'name clash' of static methods

    The background is that I am trying to design a package which allows conversion methods to be 'plugged-in' to a class within a class hierarchy so that users can choose how objects are converted to double values. (For example, a 'city-block' conversion might be used instead of the Euclidean-distance one for class TwoD below.) I am trying to use generics to ensure that only converters specific to the appropriate class can be 'plugged-in' and also to simplify the definition of new converters.
    The issue that has arisen is a case which is not 'type-safe', in that the behaviour is not what I would expect from the type specifications, yet no warning is given. The full code is below.
    public abstract class Base {
        public abstract Converter getConverter();
        public double convert() {
            return this.getConverter().convert(this); // produces a warning
    public class OneD extends Base {
        static Converter<OneD> converter;
        int x;
        public OneD(int x) {
            this.x = x;
        public static void setConverter(Converter<OneD> c) {
            converter = c;
        public Converter getConverter() {
            return converter;
    public class TwoD extends OneD {
        static Converter<TwoD> converter;
        int y;
        public TwoD(int x, int y) {
            super(x);
            this.y = y;
        public static void setConverter(Converter<TwoD> c) {
            converter = c;
        }                                   // compiles OK with no warning
        public Converter getConverter() {
            return converter;
    public abstract class Converter<T> {
        public abstract double convert(T val);
    public class OneDConverter extends Converter<OneD> {
         public double convert(OneD val) {
            return val.x;
    public class TwoDConverter extends Converter<TwoD> {
        public double convert(TwoD val) {
            return Math.sqrt(val.x * val.x + val.y * val.y);
    public class Test {
        public static void main(String[] args) {
            OneD x1d = new OneD(1);
            TwoD x2d = new TwoD(1, 1);
            OneD.setConverter(new OneDConverter());
            TwoD.setConverter(new TwoDConverter());
            System.out.println("Convert OneD(1): " + x1d.convert() +
                               ", Convert TwoD(1, 1): " + x2d.convert());
            TwoD.setConverter(new OneDConverter());
              // wrong type of converter; should not be allowed
            System.out.println("Convert OneD(1): " + x1d.convert() +
                               ", Convert TwoD(1, 1): " + x2d.convert());
    }This produces the output:
    Convert OneD(1): 1.0, Convert TwoD(1, 1): 1.4142135623730951
    Convert OneD(1): 1.0, Convert TwoD(1, 1): 1.0The first line of this shows that the all is working OK, but in the second line we see that the wrong type of converter has been plugged-in to class TwoD, with no complaints or warnings at compile or run-time. I understand why this is so (as a result of erasure), but I am surprised that no warning is given that the static method setConverter() in class TwoD clashes with the one in OneD. Is this really type-safe behaviour? (If the two methods are made instance methods instead of static, the code does not compile because of a 'name clash' error.)
    Incidentally, an 'unchecked warning' arises because of the use of the raw class Converter in class Base, but I cannot figure out how to avoid this. The warning is right, and signals that we cannot be sure that the converter is the appropriate type for the argument. It is up to subclasses to ensure this and I cannot figure out how to guarantee that it will be so.

    public abstract class Base {
    public abstract Converter getConverter();
    public double convert() {
    return this.getConverter().convert(this); // produces a warning
    }Some of the problems you're seeing can be resolved
    by organizing your code better:
    abstract class Base<T extends Base<T>> {
        public abstract Converter<T> getConverter();
        public double convert() {
            return this.getConverter().convert(getThis());
        abstract protected T getThis();
    class OneD extends Base<OneD> {
        static Converter<OneD> converter;
        int x;
        public OneD(int x) {
            this.x = x;
        public static void setConverter(Converter<OneD> c) {
            converter = c;
        public Converter<OneD> getConverter() {
            return converter;
        protected OneD getThis() { return this; }
    class TwoD extends Base<TwoD> {
        static Converter<TwoD> converter;
        int y;
        int x;
        public TwoD(int x, int y) {
            this.x = x;
            this.y = y;
        public static void setConverter(Converter<TwoD> c) {
            converter = c;
        public Converter<TwoD> getConverter() {
            return converter;
        protected TwoD getThis() { return this; }
    abstract class Converter<T> {
        public abstract double convert(T val);
    class OneDConverter extends Converter<OneD> {
         public double convert(OneD val) {
            return val.x;
    class TwoDConverter extends Converter<TwoD> {
        public double convert(TwoD val) {
            return Math.sqrt(val.x * val.x + val.y * val.y);
    class Test {
        public static void main(String[] args) {
            OneD x1d = new OneD(1);
            TwoD x2d = new TwoD(1, 1);
            OneD.setConverter(new OneDConverter());
            TwoD.setConverter(new TwoDConverter());
            System.out.println("Convert OneD(1): " + x1d.convert() +
                               ", Convert TwoD(1, 1): " + x2d.convert());
            TwoD.setConverter(new OneDConverter());  // error
            System.out.println("Convert OneD(1): " + x1d.convert() +
                               ", Convert TwoD(1, 1): " + x2d.convert());
    }

  • 2D Closest Pair Problem

    PROBLEM:
    Given an arbitrarily number of data points in 2-d space, this algorithm finds a pair of data points with minimum Euclidean distance from each other.
    I read in points from a data file as follows:
    100 //number of points
    12.5 100.2 //each line contains the x and y coordinates of one data point
    0.7 1.5
    I know it seems strange to be posting such a topic since it has been addressed several places before. I have found a decent psuedocode that addresses the algorithm:
    closestPair of (xP, yP)
                   where xP is P(1) .. P(N) sorted by x coordinate, and
                         yP is P(1) .. P(N) sorted by y coordinate (ascending order)
    if N &#8804; 3 then
      return closest points of xP using brute-force algorithm
    else
      xL &#8592; points of xP from 1 to &#8968;N/2&#8969;
      xR &#8592; points of xP from &#8968;N/2&#8969;+1 to N
      xm &#8592; xP(&#8968;N/2&#8969;)x
      yL &#8592; { p &#8712; yP : px &#8804; xm }
      yR &#8592; { p &#8712; yP : px > xm }
      (dL, pairL) &#8592; closestPair of (xL, yL)
      (dR, pairR) &#8592; closestPair of (xR, yR)
      (dmin, pairMin) &#8592; (dR, pairR)
      if dL < dR then
        (dmin, pairMin) &#8592; (dL, pairL)
      endif
      yS &#8592; { p &#8712; yP : |xm - px| < dmin }
      nS &#8592; number of points in yS
      (closest, closestPair) &#8592; (dmin, pairMin)
      for i from 1 to nS - 1
        k &#8592; i + 1
        while k &#8804; nS and yS(k)y - yS(i)y < dmin
          if |yS(k) - yS(i)| < closest then
            (closest, closestPair) &#8592; (|yS(k) - yS(i)|, {yS(k), yS(i)})
          endif
          k &#8592; k + 1
        endwhile
      endfor
      return closest, closestPair
    endif I don't understand this a 100% and how I would implement this. This has a more mathematical approach and that seems to be my problem when I look online. Is there anymore resources that anyone is aware of. Thanks for any help.

        static double d;
        private static void bruteForceClosestPair (ArrayList<Pair> points) {
            ArrayList<Pair> minPoints = new ArrayList();
            if (points.size() < 2) {
                System.out.println("Only one point!");
            else {
                d = distance (points.get(0).getX(),points.get(0).getY(), points.get(1).getX(), points.get(1).getY());
                minPoints.add(points.get(0));
                minPoints.add(points.get(1));
                for (int i = 0; i < points.size()-1;i++){
                    for (int j = i+1;j < points.size(); j++) {
                        System.out.println("Checking "+ points.get(i) +  " and " + points.get(j) );
                        if(distance(points.get(i).getX(), points.get(i).getY(), points.get(j).getX(), points.get(j).getY())< d){
                            d = distance(points.get(i).getX(), points.get(i).getY(), points.get(j).getX(), points.get(j).getY());
                            minPoints.clear();
                            minPoints.add(points.get(i));
                            minPoints.add(points.get(j));
            System.out.println("minimum is " + d);
            System.out.println("My pair points be " + minPoints.toString());
        }I am able to check every point using a brute force attack, but the problem that I am trying to accomplish is finding a divide and conquer/recursive approach to solving this problem. I hope this makes sense. How can I go about this?

  • How to track a mobile object, masking the others?

    Hi
    I work with spherical objects with a dimeter size equal to 100 micrometers. The objects are immersed in a fluid. They are movable, swimming in the fluid. I would like to track one of them, masking the others. Could somebody give me an advise how to do it?
    Regards

    Hello,
    sincu you did not attach any images it's hard to say, but check this out (a toolkit i've made, wrapping various OpenCV functions):
    https://decibel.ni.com/content/blogs/kl3m3n/2014/09/05/point-cloud-library-pcl-and-open-computer-vis...
    You could use camshift/meanshift tracking based on hue-saturation histogram backprojection, or perhaps you could just try masking your image with backprojection only.
    Spherical - since you are processing in 2D space, you can also try using Hough circle transformation to detect the circles and track them on subsequent frames using for example Euclidean distance from detected centers as your criteria.
    Can you post a sample image?
    Best regards,
    K
    https://decibel.ni.com/content/blogs/kl3m3n
    "Kudos: Users may give one another Kudos on the forums for posts that they found particularly helpful or insightful."

  • Methods - HELP!

    Just wanted to ask, I have the following method which is invoked somewhere else. I am using the eclipse development environment and have used breakpoints to see exactly where the code is not being 'followed' by the program. I know that the method is getting invoked. It works up until the first for loop and then from what I can see just goes to the brace ending the method. Can you think why this may be?
    public void euclidean(){
              theSum =new int [theCount];
              sum = new int [theRowCount][theCount];
         /* Comparing each record attribute with the next record.  The sum stores the value of the
          * differences between records (based on single attributes).  The first for stmt looks at
          * one row at a time- the second for stmt the compares this row to all the other rows.
          * For every row comparison all the attributes are considered.  NOTE: the second for stmt
          * starts at 2 so that the second row is considered (the first row is dealt with in the
          * first for stmt).*/
         for (int i=1; i<theRowCount; ++i){
              for (int all = 2; all <= theRowCount; ++all){
                   for (int k=1; k<theCount; ++k)//attributes
         /* Carry out the calculations to work out the euclidean distance.  If the attribute value being
          * considered of type int then an exception occurrs and is caught in the catch clause- if the
          * 2 values differ then the distace is equal to 1 else it is equal to 0.*/
                        try{
                             for (int c=1; c<theSum.length; ++c){
                                  theSum[c]=(sum[i][k] - sum[all][k]);
      /*Returns the squared result of the difference found between different record for the same
       * attribute.*/
                             for (int m=0; m<theSum.length; ++m )//need to square each element of theSum.
                                  theSum[m] = theSum[m]*theSum[m];
         /*Add all the attribute differences together and then square them.  Stores the resulting values
          * in an array. */
                             for (int ts=0; ts<theSum.length-1; ++ts){
                                  int tts[];
                                  tts = new int[0];/*check this-need to ensure that a value is being stored
    for all the rows, ie, don't want it so that each calculation replaces the other without the result
      being displayed in the matrix */
                                  tts[0] =tts[0]+ theSum[ts];
                                  distance = Math.sqrt((double)tts[ts]);//get square root of tts
                        }//end try
                        catch (NumberFormatException nfe){
                             if (sum[i][k] == sum[all][k]){
                                  distance = 0;
                             else if (sum[i][k] == sum[all][k]){
                                  distance =1;
                        }//end catch
      /*Devise the matrix.  For the tuples being considered ther  Squared Euclidean distance is entered in the
       * corresponding element of the array.This produces a matrix with the same number of column as rows.
       * The size of the matrix changes since it stores some calculations that
       * have been carried out on database rows. As a result the number of rows
       * that the database has is called for and this determines the size of the
       * matrix.*/
                   int row1= theRowCount, row2= theCount;
                   double [][] distanceMatrix;
                   distanceMatrix= new double [row1][row2];
                   for (i=1;i<row1; ++i){
                        for (all = 1; all<row2; ++row2)
                             distanceMatrix[i][all] =distance;
                             getMatrix(distanceMatrix);/*The distance matrix is passed call-by-refernce*/
              }

    When you are debugging your program, take a look at the values of the variables.

  • Code example of the day, want your advice

    Update: I have removed the setRunnable method and all the synchronization stuff, which takes care of question a. Now, on part B, can anyone suggest a better name for this class?
    I am posting my class ThreadForMultipleAnytimeRuns, plus my Eyes class which was actually the reason I created it.
    ThreadForMultipleAnytimeRuns offers the following:
    (a) you can run a runnable outside of the GUI thread - important in this case, because if you try to run an animation in the drawing thread you're not going to see anything
    (b) It will queue the blinks so they don't all happen at once.
    Questions:
    1. Is what I've done thread-safe? I added a method to swap the runnable into the class. I have it so that it waits until the job queue (semaphore) is empty before it swaps in the new runnable. Is this safe now? I would love to hear your thoughts
    2. I am unsatisfied with the name of this class. Can anyone think of a better name?
    BTW, unfortunately this code isn't compilable as posted. To get it to compile, you need to remove the references to MathUtils - all this takes is replacing distance with the euclidean distance formula, and angle with java.lang.Math.atan2, and references to WindowUtilities, which means replacing WindowUtilities.visualize and just building a JFrame and sticking the eyes in it
    Thanks for any comments about how I could make this better!
    You are welcome to use and modify this code, but please don't change the package or take credit for it as your own code.
    package tjacobs.thread;
    import java.awt.Dimension;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.util.concurrent.Semaphore;
    import javax.swing.JFrame;
    import tjacobs.ui.Eyes;
    import tjacobs.ui.WindowUtilities;
    public class ThreadForMultipleAnytimeRuns extends Thread {
         private Runnable mRunnable;
         private Semaphore mSemaphore;
         public ThreadForMultipleAnytimeRuns(Runnable arg0) {
              super();
              init(arg0);
         private void init(Runnable r) {
              mRunnable = r;
              mSemaphore = new Semaphore(0);
              setDaemon(true);
         public ThreadForMultipleAnytimeRuns(Runnable arg0, String arg1) {
              super(arg1);
              init(arg0);
         public ThreadForMultipleAnytimeRuns(ThreadGroup arg0, Runnable arg1, String arg2) {
              super(arg0, arg2);
              init(arg1);
         public void run () {
              try {
                   while (!isInterrupted()) {
                        // make a local copy so if mRunnable changes
                        // we have the fresh one
                        mSemaphore.acquire();
                        if (getSemaphoreCount() == 0) {
                             Runnable r = mRunnable;
                             synchronized (this) {
                                  notifyAll();
                             r.run();
                        mRunnable.run();
              catch (InterruptedException ex) {}
         public void runAgain() {
              mSemaphore.release();
         public void runAgain(int numTimes) {
              mSemaphore.release(numTimes);
         public void stopThread() {
              interrupt();
         public int getSemaphoreCount() {
              return mSemaphore.availablePermits();
         public Runnable getRunnable() {
              return mRunnable;
         public synchronized void setRunnable(Runnable r) {
              if (getSemaphoreCount() > 0) {
                   try {
                        wait();
                   catch (InterruptedException ex) {
                        return;
              mRunnable = r;
         public static void main(String[] args) {
              final Eyes eyes = new Eyes(true);
              //eyes.addMouseMotionListener(eyes);
              Runnable r = new Runnable() {
                   public void run() {
                        eyes.blink();
                        try {
                             Thread.sleep(100);
                        catch(InterruptedException ex) {}
              final ThreadForMultipleAnytimeRuns ar = new ThreadForMultipleAnytimeRuns(r);
              ar.start();
              eyes.addMouseListener(new MouseAdapter() {
                   public void mouseClicked(MouseEvent me) {
                        ar.runAgain();
              eyes.setPreferredSize(new Dimension(60,20));
              WindowUtilities.visualize(eyes);
    //          JFrame jf = new JFrame();
    //          jf.add(eyes);
    //          jf.pack();
    //          jf.setLocation(100,100);
    //          jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    //          jf.setVisible(true);
    ================================================
    tjacobs.ui.Eyes
    ============
    package tjacobs.ui;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Point;
    import java.awt.Rectangle;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseMotionListener;
    import java.util.Timer;
    import java.util.TimerTask;
    import javax.swing.JComponent;
    import javax.swing.SwingUtilities;
    import tjacobs.MathUtils;
    public class Eyes extends JComponent implements MouseMotionListener {
         private int mEyeGap = 0;
         private double mEyeDir1 = Double.NaN, mEyeDir2 = Double.NaN;
         private double mEyeRatio = .6;
         private int mBlinkEyesState = 0;
         private Timer mEyeBlinker;
         private long mTimeBetweenBlinks;
         private long mBlinkAnimationSpeed = 100;
         public Eyes() {
              //setBackground(Color.BLACK);
              this(false);
         public Eyes(boolean watchOnEyes) {
              setBackground(Color.PINK);
              setForeground(Color.BLUE);
              if (watchOnEyes) addMouseMotionListener(this);          
         public void setBatAnimationSpeed(long speed) {
              mBlinkAnimationSpeed = speed;
         public long getBatAnimationSpeed() {
              return mBlinkAnimationSpeed;
         public void mouseMoved(MouseEvent me) {
              Point p = SwingUtilities.convertPoint(me.getComponent(), me.getPoint(), this);
              int height = getHeight();
              mEyeDir1 = MathUtils.angle(height / 2, height / 2, p.x, p.y);
              mEyeDir2 = MathUtils.angle((3 * height) / 2 + mEyeGap, height / 2, p.x, p.y);
              repaint();
         public void mouseDragged(MouseEvent me) {
              mouseMoved(me);
         public int getEyeGap() {
              return mEyeGap;
         public void setEyeGap(int gap) {
              mEyeGap = gap;
         public void setBlinkEyes(long timeBetweenBlinks) {
              mTimeBetweenBlinks = timeBetweenBlinks;
              if (mEyeBlinker != null) {
                   mEyeBlinker.cancel();
                   mEyeBlinker = null;
              if (timeBetweenBlinks < mBlinkAnimationSpeed * 8) {
                   return;
              else {
                   mEyeBlinker = new Timer(true); //allow it to be a daemon thread
                   mEyeBlinker.scheduleAtFixedRate(new BlinkEyesTask(), mTimeBetweenBlinks, mTimeBetweenBlinks);
                   //Thread t = new Thread(mEyeBlinkter);
                   //t.start();
          * makes the eyes blink
          * this method will not function correctly if it is run in the
          * GUI painter thread, as it handles the whole process and calls
          * repaint() sleep() in between steps.
         public void blink() {
              try {
                   //System.out.println("bat");
                   Thread t = Thread.currentThread();
                   mBlinkEyesState = 1;
                   repaint();
                   t.sleep(mBlinkAnimationSpeed);
                   mBlinkEyesState = 2;
                   repaint();
                   t.sleep(mBlinkAnimationSpeed);
                   mBlinkEyesState = 3;
                   repaint();
                   t.sleep(mBlinkAnimationSpeed);
                   mBlinkEyesState = 4;
                   repaint();
                   t.sleep(mBlinkAnimationSpeed);
                   mBlinkEyesState = 3;
                   repaint();
                   t.sleep(mBlinkAnimationSpeed);
                   mBlinkEyesState = 2;
                   repaint();
                   t.sleep(mBlinkAnimationSpeed);
                   mBlinkEyesState = 1;
                   repaint();
                   t.sleep(mBlinkAnimationSpeed);
                   mBlinkEyesState = 0;
                   repaint();
              catch (InterruptedException ex) {
                   if (mBlinkEyesState != 0) {
                        mBlinkEyesState = 0;
                        repaint();
         private class BlinkEyesTask extends TimerTask {
              public void run() {
                   blink();
          * @param angle Either Double.NaN for center, or a value between 0 and 2 PI
         public void setEye1Direction(double angle) {
              mEyeDir1 = angle;
         public double getEye1Direction() {
              return mEyeDir1;
          * @param angle Either Double.NaN for center, or a value between 0 and 2 PI
         public void setEye2Direction(double angle) {
              mEyeDir1 = angle;
         public double getEye2Direction() {
              return mEyeDir2;
         public void paintComponent(Graphics g) {
              int height = getHeight();
              int r = height / 2;
              g.setColor(Color.WHITE);
              g.fillOval(0, 0, height, height);
              g.fillOval(height + mEyeGap + 0, 0, height, height);
              g.setColor(Color.BLACK);
              g.drawOval(0, 0, height, height);
              g.drawOval(height + mEyeGap + 0, 0, height, height);
              g.setColor(getForeground());
              int irisR = (int) (r * mEyeRatio);
              if (Double.isNaN(mEyeDir1)) {
                   int x1 = (r - irisR);
                   int y1 = x1;
                   g.fillOval(x1, y1, irisR * 2, irisR * 2);
              } else {
                   int x1 = (r - irisR);
                   int y1 = x1;
                   x1 -= Math.cos(mEyeDir1) * (r - irisR);
                   y1 -= Math.sin(mEyeDir1) * (r - irisR);
                   g.fillOval(x1, y1, irisR * 2, irisR * 2);
              if (Double.isNaN(mEyeDir2)) {
                   int x1 = (r - irisR) + height + mEyeGap;
                   int y1 = (r - irisR);
                   g.fillOval(x1, y1, irisR * 2 , irisR * 2);               
              } else {
                   int x1 = (r - irisR) + height + mEyeGap;
                   int y1 = r - irisR;
                   x1 -= Math.cos(mEyeDir2) * (r - irisR);
                   y1 -= Math.sin(mEyeDir2) * (r - irisR);
                   g.fillOval(x1, y1, irisR * 2, irisR * 2);
    //          OLD
    //          if (Double.isNaN(mEyeDir1)) {
    //               int x1 = (r - irisR);
    //               int y1 = x1;
    //               g.fillOval(x1, y1, irisR * 2, irisR * 2);
    //               x1 += height + mEyeGap;
    //               g.fillOval(x1, y1, irisR * 2 , irisR * 2);               
    //          } else {
    //               int x1 = (r - irisR);
    //               int y1 = x1;
    //               x1 -= Math.cos(mEyeDir1) * (r - irisR);
    //               y1 -= Math.sin(mEyeDir1) * (r - irisR);
    //               g.fillOval(x1, y1, irisR * 2, irisR * 2);
    //               x1 = (r - irisR) + height + mEyeGap;
    //               y1 = r - irisR;
    //               x1 -= Math.cos(mEyeDir2) * (r - irisR);
    //               y1 -= Math.sin(mEyeDir2) * (r - irisR);
    //               g.fillOval(x1, y1, irisR * 2, irisR * 2);
              //Eye Blinking
              if (mBlinkEyesState != 0) {
                   Rectangle rect = new Rectangle(0,0,getWidth(), getHeight() * mBlinkEyesState / 4);
                   g.setClip(rect);
                   g.setColor(getBackground());
                   g.fillOval(0, 0, height, height);
                   g.fillOval(height + mEyeGap + 0, 0, height, height);
          * @param args
         public static void main(String[] args) {
              // TODO Auto-generated method stub
              Eyes eyes = new Eyes(true);
              eyes.setBlinkEyes(10000);
              eyes.setPreferredSize(new Dimension(60,25));
              eyes.setEyeGap(5);
              WindowUtilities.visualize(eyes);
    }Message was edited by:
    tjacobs01

    So, if you shake the panel long enough, do the
    contents disappear? :Dno but they get a big headache

  • How does ODM cluster algorithm work?

    I know ODM cluster analysis uses an enhanced k-means algorithm which randomly defines the initial centroids.
    1. I'd like to know how ODM cluster analysis algorithm defines initial centroids?
    It doesn't seem to randomly define initial centroids because every time I ran
    ODM clustering, it gave the same results.
    2. To calculate the distance between a centroid and data objects, Euclidean
    distance is used. If the data object is categorical attributes how the distance is
    calculated?
    Could you please help me on these?
    I will be looking forward your help on these and appreciate your help.

    1.ODM k-means builds a hierarchical tree. When a new cluster is added, the parent node is replaced with two new nodes. Both children have the same centroid as the parent except for a small perturbation in the dimension with most variablility. Then a few k-means iterations are run on the two children and the points belonging to the parent are distributed among the two new nodes. There are a couple of different strategies how to choose which node to split (e.g., size, dispersion).
    Once the desired number of leaf nodes is reached, we run k-means across all leaf nodes. The advantage is that all clusters have reasonable initial centroids and we are unlikely to get dead/empty clusters.
    2. We explode categorical attributes into multiple binary dimensions and compute distances using these new dimensions.

  • Floyds Algorithm for path finding

    I'm currently trying to figure out which path finding algorithm to use in my game. It seems most people prefer A* and I don't quite get it.
    I must be missing something because as I see it Floyds Algorithm is superior in many respects.
    1) You are guaranteed to get an optimal rout.
    2) It's all precomputed, so you just have to look up the rout in a matrix.
    What am I missing ?
    Kim

    A* is guaranteed to find the shortest path, as long as the function you use for the heuristic is an underestimate of the actual distance. For example, say you have a square grid where some tiles are blocked by obstacles while others aren't; then you can use the Euclidean distance (sqrt(deltaX^2 + deltaY^2)) between two tiles as your heuristic, since real paths will be as long as that, and A* will find the shortest path. Even if you use an overestimate for a heuristic, A* will find some path if a path exists; it will find it faster in fact, but it won't necessarily be the best path. Often people use overestimates on purpose in practice because this saves a lot of time and still finds pretty good paths.
    Floyd's algorithm has a worse running-time than A* because A* can get "hints" of which direction to go towards while Floyd's essentially checks all possibilities. It's true that you can use it to obtain the all-pairs shortest-paths matrix however, in which case it is certainly faster than using A* on every pair of points to find the path between them (since the heuristic only gives distance to one goal). The problem is that in most games the world changes at run-time however - for example someone builds a building or chops down a tree, or someone blocks a door, or there are people in the AI object's way. Also, sometimes you try to find the path that is not shortest but also "safest" in some way - increase costs of tiles where you've seen a lot of enemy activity for example in order to avoid them, and this information changes at runtime. Recalculating the all-pairs shortest-paths matrix gets expensive then, especially in the case of moving obstacles like human players. If you have a game where the obstacles are fixed however and the map size isn't so big that an N^3 algorithm (Floyd) wouldn't do it, then do precalculate the paths.

  • SDO_NN with Oracle Spatial

    Hello,
    although the description of my problem is a bit long, I hope you could help me.
    I would like to compute the nearest neighbor of a point being located on the surface of the unit sphere.
    For that query, I would like to take advantage of the features provided by Oracle Spatial (10g).
    Table spatial_test contains the columns point_name, x, y, z, ra, dec where:
    point_name is the primary key
    x, y, z are the coordinates of the points on the unit sphere (so x^2+y^2+z^2=1)
    ra, dec are the the concerning spherical coordinates where the following conditions hold: x=cos(dec)*cos(ra) , y=cos(dec)*sin(ra), z=sin(dec).
    For computing the nearest neighbor of a point with point_name='point1' the query without using Oracle Spatial is:
    select * from(
    select
    acos(t1.x*t2.x+t1.y*t2.y+t1.z*t2.z) as distance, t1.*
    from spatial_test t1,
    spatial_test t2
    where t2.point_name='point1'
    and t1.name != t2.name
    order by dist
    where rownum<2;
    For taking advantage of Oracle Spatial, I have to prepare my data doing the following five steps:
    1. add a column to of type SDO_GEOMETRY to table spatial_test
    2. insert values to that table
    3. update table user_sdo_geom_metadata
    4. create the spatial index
    5. execute the following query on the amended table spatial_test:
    SELECT t1.point_name name1, t2.point_name name2 FROM spatial_test t1, spatial_test t2
    WHERE SDO_NN(t2.geom, t1.geom, 'sdo_num_res=2') = 'TRUE'
    and t1.point_name = 'point1'
    and t1.point_NAME != t2.point_name
    As mentioned in the User Guide for Oracle Spatial, only two dimensional objects are supported.
    So, if I insert tuples in the following form to my table:
    insert into spatial_test (point_name, x, y, z, geom) values (..., ..., ..., ...,
    SDO_GEOMETRY(3001,
    NULL, --SDO_SRID is null, so no coordinate system is associated with the geometry
    SDO_POINT_TYPE(x_value, y_value, z_value),
    NULL,
    NULL));
    I won't get the correct results. I assume that the z_value is just ignored. Am I right with that assumption?
    For using Oracle Spatial, I have to use the equivalent just using two dimensions. Since ra, dec is another representation for x, y, z, I tried to do the same, just using ra and dec. But here, my results also differ from the ones computed with my own computation of the nearest neighbor.
    Here an minimal example which shows my problem:
    CREATE TABLE spatial_test(
    point_name varchar(20) PRIMARY KEY,
    x float,
    y float,
    z float,
    ra float,
    dec float,
    geom SDO_GEOMETRY);
    -- INSERT POINTS --
    insert into spatial_test(point_name, x, y, z, ra, dec, geom) values ('point1', -0.00472924, 0.110927216, 0.99381728, 92.44125, 83.62542,
    SDO_GEOMETRY(2001, -- 2 dimensions, last dimension is the measure, geometry type 01 = point
    NULL, --SDO_SRID is null, so no coordinate system is associated with the geometry
    SDO_POINT_TYPE(92.44125, 83.62542, null),
    NULL,
    NULL));
    insert into spatial_test(point_name, x, y, z, ra, dec, geom) values ('point2', -0.00239923, 0.112814014, 0.993613226, 91.21833, 83.52097,
    SDO_GEOMETRY(2001, -- 2 dimensions, last dimension is the measure, geometry type 01 = point
    NULL, --SDO_SRID is null, so no coordinate system is associated with the geometry
    SDO_POINT_TYPE(91.21833, 83.52097, null),
    NULL,
    NULL));
    insert into spatial_test(point_name, x, y, z, ra, dec, geom) values ('point3', -0.00701052, 0.122780703, 0.992409065, 93.26792, 82.93584,
    SDO_GEOMETRY(2001, -- 2 dimensions, last dimension is the measure, geometry type 01 = point
    NULL, --SDO_SRID is null, so no coordinate system is associated with the geometry
    SDO_POINT_TYPE(93.26792, 82.93584, null),
    NULL,
    NULL));
    -- UPDATA user_sdo_geom_metadata --
    INSERT INTO user_sdo_geom_metadata
    (TABLE_NAME,
    COLUMN_NAME,
    DIMINFO,
    SRID)
    VALUES (
    'spatial_test',
    'geom',
    MDSYS.SDO_DIM_ARRAY(
    MDSYS.SDO_DIM_ELEMENT('ra', 0.0, 360.0, 0.0000000000001),
    MDSYS.SDO_DIM_ELEMENT('dec', -90.0, 90.0, 0.0000000000001)
    NULL -- no specific coordinate system should be associated with the geometries.
    -- CREATE THE SPATIAL INDEX --
    CREATE INDEX spatial_test_idx
    ON spatial_test(geom)
    INDEXTYPE IS MDSYS.SPATIAL_INDEX;
    Now I could execute the following queries which should both compute the nearest neighbor of 'point1'.
    This is the statement computing the nearest neighbor without Oracle Spatial:
    select * from(
    select
    acos(t1.x*t2.x+t1.y*t2.y+t1.z*t2.z) as distance, t2.point_name p1, t1.point_name p2
    from spatial_test t1,
    spatial_test t2
    where t2.point_name='point1'
    and t1.point_name != t2.point_name
    order by distance
    where rownum<2;
    RESULT:
    DISTANCE P1 P2
    ,003005107 point1 point2
    With the following statement, I compute the nearest neighbor of 'point1' using Oracle Spatial:
    SELECT t1.point_name name1, t2.point_name name2 FROM spatial_test t1, spatial_test t2
    WHERE SDO_NN(t2.geom, t1.geom, 'sdo_num_res=2') = 'TRUE'
    and t1.point_name = 'point1'
    and t1.point_NAME != t2.point_name;
    RESULT:
    NAME1 NAME2
    point1 point3
    As you see, unfortunately, the two results differ.
    Could you please tell me, what I understood wrong in using Oracle Spatial?
    In addition, what kind of coordinate system is assumed if it isn't specified in my SDO_GEOMETRY? Which kind of distance is computed using sdo_nn (euclidean distance, ...)?
    Would be glad, if you could tell how to reach the same results for my nearest neighbors using Oracle Spatial.
    Regards,
    Ina

    I would like to compute the nearest neighbor of a
    point being located on the surface of the unit
    sphere.That would be a spherical 3D computation. Currently, OS does not work well with 3D such as spheres, sorry. I know R2 was supposed to improve on this for cubes and pyramids, but to be honest; I haven’t had time to go back and test the simple cube operations. With 10gR1, for most of the operators and functions 2,2,3 and 2,2,5 are same point. I know this is something that is being worked on, possibly Dan can comment further.
    See for more info:
    Re: 3D Polygon
    For now, if you have your own routines, I’d use them as a package instead. If you need help there, let us know and we’ll try to point you in the right direction or help you to translate the code to PL/SQL.
    Bryan

  • Lab Color Range

    Hi
    In Photoshop the a and b values in Lab color range from -128 to 127, but on wikipedia (http://en.wikipedia.org/wiki/Lab_color#Range_of_L.2Aa.2Ab.2A_coordinates) they are -0.86 to 0.98 and -1.07 to 0.94 respectively. Is this just a usability thing in Photoshop? Can I plot the Photoshop values on a graph (http://en.wikipedia.org/wiki/Image:CIExy1931.svg) by using ratios to convert the values?
    Thanks!
    Chris

    Hello Chris,
    What are you trying to do? Do you want to get into all the math and complexities of 3 dimensional space and Euclidean Distances or are you interested in understanding and using LAB for practical purposes. If it's the latter, then there are a lot of tutorials floating around and the Photoshopper's bible on lAB - a book by Dan Margulis called "The Canyon Conundrum and Other Adventures in the World's Most Powerful Color Space". If however you want to get into all the math and science, you would probably be better off checking out the CIE org.
    Regards, MM

  • 3D Graph Layout Algorithms?

    Hello there! I'm developing a project for my first computer science thesis at the university of Bari, Italy. This project consists in a OpenGL graph visualization tool but I'm having trouble in implementing a correct layout algorithm.
    The problem is that I have been unable to find any information regarding the actual algorithms.. all I've discovered is that there are many commercial products out there that implement these algorithms.. :) I need to know how to implement them myself!
    I have a set of spheres (and the x-y-z coordinates of their center), and a set of edges which describe the various connection between those spheres. I'm currently using a sort of very simple spring embedder algorithm which works in this way:
    Phase 1:
    get sphere 1 (s1)
    get sphere 2 (s2)
    check s1 against all other spheres
    if their euclidean distance is too small they are moved farther away in this way:
    if (s1.x < s2.x)
    s1.x -= delta
    s2.x += delta
    if (s1.y < s2.y)
    s1.y -= delta
    and so on. This is the only way to avoid collisions between spheres that I thought of, since they are not puntiform in fact they have a certain radious. Then in phase 2 I iterate between all the edges and if two connected spheres are too distant from each other they are moved nearer in a way like the one described above. But it doesn't seem to work as it should in fact this algorithm seems to lock the spheres after a number of iteration but rarely produces pleasing visual configurations.
    So could anyone please point me in the right direction? What kind of algorithm could I use? A description would be very useful.. Thanks in advance!

    Hi, I am coauthor and developer of some of the spring-embedder algorithms used in the Java graph layout library 'yFiles' (we call them 'organic layout algorithms'). Some of the algorithms actually work in 3D and all of them can be adapted very easily to run in 3D. We are using combinations and variants and enhanced versions of some of the following algorithms, as well as some of our own, but for a starter this should be enough information for you:
    google for 'GRIP layout' 'GUIDE layout', Kamada-Kawai, Fruchterman-Reingold, Eigenvalue graph layout, GEM spring embedder,
    Implementing those algorithms well can lead to very nice results: feel free to take a look at our gallery of graph layouts:
    http://www.yworks.com/en/products_yfiles_practicalinfo_gallery.htm
    Regards, and a happy new year, Sebastian

  • Making clickable hex grids

    I try to implement MouseListener by using
    public class HexBoard extends Frame implements MouseListenerbut the error message says I need to define the class as a abstract class. After trying that, i still get a error message in main says my class constructor is wrong. can anyone here help me please
    import java.awt.*;
    import java.awt.event.*;
    public class HexBoard extends Frame {
        public static int board_size = 7;
        public static int width = 980;
        public static int height = 600;
        private static int cellSize = width / (board_size + 20);
        public static int radius = (cellSize + cellSize / 4) / 2;
        public static int center_x = width / 2 - radius / 4;
        public static int center_y = (height - radius) / 2;
        public static double[][] grids;
        public HexBoard() {
            grid();
            this.setSize(980, 600);
            this.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    System.exit(0);
        public void init() {
            grid();
        //addMouseListener(this);
        private void drawNeck(Graphics g, double x, double y, double r, int n, boolean filled) {
            Polygon p = new Polygon();
            for (int i = 0; i < n; i++) {
                p.addPoint((int) (x + r * Math.cos(i * 2 * Math.PI / n)),
                        (int) (y + r * Math.sin(i * 2 * Math.PI / n)));
            if (filled == true) {
                g.fillPolygon(p);
            } else {
                g.drawPolygon(p);
    //Draws a n-Eck polygon with the given parameter
        public void drawNeck(Graphics g, double x, double y, double r, int n) {
            drawNeck(g, x, y, r, n, false);
    //Draws a filled n-Eck polygon with the given parameter
        public void fillNeck(Graphics g, double x, double y, double r, int n) {
            drawNeck(g, x, y, r, n, true);
        //Draws oval
        public void draw_oval(Graphics g, double x, double y) {
            x = x - radius * Math.sqrt(2) * 0.5;
            y = y - radius * Math.sqrt(2) * 0.5;
            int x_value = (int) x;
            int y_value = (int) y;
            double r = radius * 1.5;
            int rr = (int) r;
            g.drawOval(x_value, y_value, rr, rr);
        //Draws oval
        public void draw_filloval(Graphics g, double x, double y) {
            x = x - radius * Math.sqrt(2) * 0.5;
            y = y - radius * Math.sqrt(2) * 0.5;
            int x_value = (int) x;
            int y_value = (int) y;
            double r = radius * 1.5;
            int rr = (int) r;
            g.fillOval(x_value, y_value, rr, rr);
    //here the paint method which needs to be modificated
        public void paint(Graphics g) {
            for (int i = 0; i < board_size * board_size; i++) {
                //draw_oval(g, grids[0], grids[i][1]);
    //draw_filloval(g, grids[i][0], grids[i][1]);
    drawNeck(g, grids[i][0], grids[i][1], radius, 6);
    // find the center of hexagon grids
    public void grid() {
    int count = 0;
    grids = new double[board_size * board_size][2];
    grids[0][1] = center_y;
    if (board_size % 2 != 0) {
    grids[0][0] = center_x - radius * (board_size + num_odd(board_size) - 1);
    } else if (board_size % 2 == 0) {
    System.out.printf("even");
    grids[0][0] = center_x - radius * (board_size + num_even(board_size) - 1) + radius / 2;
    for (int i = 1; i < board_size * board_size; i++) {
    count = count + 1;
    if (count == board_size) {
    count = 0;
    grids[i][0] = grids[i - board_size][0] + radius + radius / 2;
    grids[i][1] = grids[i - board_size][1] - radius * Math.sqrt(3) * 0.5;
    } else {
    grids[i][0] = grids[i - 1][0] + radius + radius / 2;
    grids[i][1] = grids[i - 1][1] + radius * Math.sqrt(3) * 0.5;
    // finds the number of odd numbers smaller than a bigger odd number
    public static int num_odd(int size) {
    int[] temp = new int[board_size];
    int num_odd = 0;
    int count = 0;
    for (int i = 0; i < size; i++) {
    temp[i] = count;
    if (temp[i] % 2 != 0) {
    num_odd = num_odd + 1;
    count = count + 1;
    return num_odd;
    // finds the number of even numbers smaller than a bigger even number
    public static int num_even(int size) {
    int[] temp = new int[board_size];
    int num_even = 0;
    int count = 0;
    for (int i = 0; i < size; i++) {
    temp[i] = count;
    if (temp[i] % 2 == 0) {
    num_even = num_even + 1;
    count = count + 1;
    System.out.printf("dd " + num_even);
    return num_even;
    public void changeSize(int size) {
    board_size = size;
    repaint();
    public void mouseReleased(MouseEvent e) {
    public static void main(String args[]) {
    HexBoard hex = new HexBoard();
    hex.setSize(width, height);
    hex.setVisible(true);
    }Edited by: gamewell on Apr 22, 2008 12:16 PM
    Edited by: gamewell on Apr 22, 2008 12:17 PM
    Edited by: gamewell on Apr 22, 2008 12:18 PM                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

    well, i didn't build the tile marix in the end. Instead, I calculated Euclidean distance between the hex grids center and a mouse Cursor point using nearest neighebor algorithm.
        public int CursorToGrid (int x, int y) {
            int grid_index = -1;
            double temp = Integer.MAX_VALUE;
            double distance[] = new double [board_size*board_size];
            // find the nearst neighbor using Euclidean distance
            for (int i = 0; i < board_size * board_size; i++) {
                distance[i] = Math.sqrt(Math.pow(grids[0]-x,2)+Math.pow(grids[i][1]-y,2));
    System.out.println(distance[i]);
    if (distance[i] < temp) {
    temp = distance[i];
    grid_index = i;
    // check if a click outsite the hex map
    if ( distance[grid_index] > radius) {
    grid_index = 10000;
    System.out.println("the grid " + grid_index);
    return grid_index;
    works:D                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

Maybe you are looking for

  • Error for output tax code:Tax code I4 may only contain one assignment line.

    Hi While posting customer invoice with output tax code, I am getting following error. Tax code I4 may only contain one assignment line. Please help me resolve. Regards Rekha

  • Error during creation of  Planning Version in SAP - ICH

    Hi All, I'm working on SAP-ICH, in that i tried to create planning version after creating the planning model but the system is giving information " General error in model/planning version management " . Could you please tell me the reason why this is

  • Update a table from a view (WITH)

    Hello, Is the below valid? Can I update table1 from table2 (view)? Oracle is 9i UPDATE WITH t2 AS ( SELECT.................... SELECT t1.name n1, t2.name n2 FROM cell_info t1, t2 WHERE t1.cell = t2.cell AND t1.name IS NULL SET n1 = n2; SQL Error: ORA

  • Client variables not working in Apache and CF8

    I have Apache and CF8 set up with multiple virtual hosts locally for development(win xp pro, apache 2.2.4) Client variables are not working. I can log into CF administrator fine(not sure if authentication uses client variables or not). Any site that

  • Business Logic Editor with Complex Transasctions

    I'm starting to have some serious problems using the Business Logic Editor with reasonably large (but by no means huge) transactions. These transactions also have nested transaction calls down a few layers. The main symptoms are: 1)  When opening the