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 meThat 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..?
ThanksThere 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());
} -
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 ≤ 3 then
return closest points of xP using brute-force algorithm
else
xL ← points of xP from 1 to ⌈N/2⌉
xR ← points of xP from ⌈N/2⌉+1 to N
xm ← xP(⌈N/2⌉)x
yL ← { p ∈ yP : px ≤ xm }
yR ← { p ∈ yP : px > xm }
(dL, pairL) ← closestPair of (xL, yL)
(dR, pairR) ← closestPair of (xR, yR)
(dmin, pairMin) ← (dR, pairR)
if dL < dR then
(dmin, pairMin) ← (dL, pairL)
endif
yS ← { p ∈ yP : |xm - px| < dmin }
nS ← number of points in yS
(closest, closestPair) ← (dmin, pairMin)
for i from 1 to nS - 1
k ← i + 1
while k ≤ nS and yS(k)y - yS(i)y < dmin
if |yS(k) - yS(i)| < closest then
(closest, closestPair) ← (|yS(k) - yS(i)|, {yS(k), yS(i)})
endif
k ← 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?
RegardsHello,
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." -
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:
tjacobs01So, 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 ?
KimA* 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,
InaI 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 havent 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, Id use them as a package instead. If you need help there, let us know and well try to point you in the right direction or help you to translate the code to PL/SQL.
Bryan -
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!
ChrisHello 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 -
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 PMwell, 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