Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.io.FileNotFoundException;
- import java.io.PrintWriter;
- import java.util.*;
- public class Trilateration3D {
- public static void main(String[] args) throws FileNotFoundException {
- //Redosled na vnesuvanje:
- //public WSN(int N, int anchorPer, double R, double L, double noise)
- int N, anchorPer;
- double R, L, noise;
- Scanner s = new Scanner(System.in);
- System.out.println("N - vkupen broj na jazli, anchorPer - procent na anchor jazli");
- System.out.println("L - dolzina, R - radio opseg, noise - procent na sum");
- System.out.println("\nIzberi grafik: ");
- System.out.println("1: ANCHORS vs NOISE 2: NOISE vs ERROR 3: RANGE vs CONNECTIVITY");
- int c = Integer.parseInt(s.nextLine());
- if(c == 1)
- {
- System.out.println("Vnesi po red: N - R - L - noise");
- String line = s.nextLine();
- String []parts = line.split(" ");
- N = Integer.parseInt(parts[0]);
- R = Double.parseDouble(parts[1]);
- L = Double.parseDouble(parts[2]);
- noise = Double.parseDouble(parts[3]);
- //Test1(int N, double R, double L, double noise)
- Test1(N,R,L,noise);
- }
- else if(c == 2)
- {
- System.out.println("Vnesi po red: N - anchorPer - R - L");
- String line = s.nextLine();
- String []parts = line.split(" ");
- N = Integer.parseInt(parts[0]);
- anchorPer = Integer.parseInt(parts[1]);
- R = Double.parseDouble(parts[2]);
- L = Double.parseDouble(parts[3]);
- //Test2(int N, int anchorPer,double R, double L)
- Test2(N, anchorPer, R, L);
- }
- else if (c == 3){
- System.out.println("Vnesi po red: N - anchorPer - L - noise");
- String line = s.nextLine();
- String []parts = line.split(" ");
- N = Integer.parseInt(parts[0]);
- anchorPer = Integer.parseInt(parts[1]);
- L = Double.parseDouble(parts[2]);
- noise = Double.parseDouble(parts[3]);
- //Test3(int N, int anchorPer, double L, double noise)
- Test3(N, anchorPer, L, noise);
- }
- }
- public static void Test1(int N, double R, double L, double noise) throws FileNotFoundException{ //ANCHOR PERCENT vs ERROR
- PrintWriter pw = new PrintWriter("F:/FINKI/VI semestar/Senzorski sistemi/Trilateration/anchors.txt");
- /* int anchorPer = 10;
- double L = 300;
- int N = 200;
- double R = 60;
- double noise = 10;
- */
- int anchorPer = 10;
- while(anchorPer < 100)
- {
- double error = 0;
- for(int j = 0; j < 30; j++)
- {
- WSN wsn = new WSN(N, anchorPer, R, L, noise);
- wsn.calculate();
- // System.out.println(String.format("N: %d, anchorPer: %d, R: %.2f, L: %.2f, noise: %.2f", N, anchorPer,R,L,noise));
- double err = wsn.calculateError();
- error+= err;
- }
- error /=30;
- StringBuilder sb = new StringBuilder();
- sb.append(String.format("%d %.3f",anchorPer,error));
- System.out.println(String.format("ANCHORS: %d ERROR: %.3f",anchorPer,error));
- pw.println(sb.toString());
- anchorPer+=5;
- }
- pw.close();
- }
- public static void Test2(int N, int anchorPer,double R, double L) throws FileNotFoundException{ //NOISE vs ERROR
- PrintWriter pw = new PrintWriter("F:/FINKI/VI semestar/Senzorski sistemi/Trilateration/noise.txt");
- double noise = 10;
- while(noise < 100)
- {
- double error = 0;
- for(int j = 0; j < 30; j++)
- {
- WSN wsn = new WSN(N, anchorPer, R, L, noise);
- wsn.calculate();
- // System.out.println(String.format("N: %d, anchorPer: %d, R: %.2f, L: %.2f, noise: %.2f", N, anchorPer,R,L,noise));
- double err = wsn.calculateError();
- error+= err;
- }
- error /=30;
- StringBuilder sb = new StringBuilder();
- sb.append(String.format("%.3f %.3f",noise,error));
- System.out.println(String.format("NOISE: %.3f ERROR: %.3f",noise,error));
- pw.println(sb.toString());
- noise+=5;
- }
- pw.close();
- }
- public static void Test3(int N, int anchorPer, double L, double noise) throws FileNotFoundException{ //RANGE vs AVERAGE NUMBER OF NEARBY ANCHORS
- PrintWriter pw = new PrintWriter("F:/FINKI/VI semestar/Senzorski sistemi/Trilateration/range.txt");
- double R = 10;
- while(R < L)
- {
- double avg = 0;
- for(int j = 0; j < 30; j++)
- {
- WSN wsn = new WSN(N, anchorPer, R, L, noise);
- wsn.calculate();
- avg+=wsn.avgNeighbors();
- if(R == 40)
- {
- wsn.getCoordinatesForVisualization();
- }
- }
- avg/=30;
- StringBuilder sb = new StringBuilder();
- sb.append(String.format("%.3f %.3f",avg,R));
- System.out.println(String.format("RADIO RANGE: %.3f AVERAGE NUMBER OF NEARBY ANCHORS: %.3f",R, avg));
- pw.println(sb.toString());
- R+=10;
- }
- pw.close();
- }
- }
- class Node{
- double X,Y,Z;
- boolean anchor;
- boolean original;
- double Xs,Ys,Zs;
- List<Node> nearbyAnchors; //anchors vo radio opseg na jazolot
- List<Double> distanceFromAnchors;
- List<Node> points;
- List<Node> innerPoints;
- public Node(double X, double Y, double Z,boolean anchor){
- this.X = X;
- this.Y = Y;
- this.Z = Z;
- this.anchor = anchor;
- if(anchor)
- {
- original = true;
- Xs = X;
- Ys = Y;
- Zs = Z;
- }
- else {
- original = false;
- Xs = 0;
- Ys = 0;
- Zs = 0;
- }
- nearbyAnchors = new ArrayList<Node>();
- points = new ArrayList<Node>();
- innerPoints = new ArrayList<Node>();
- }
- public boolean calculateCoordinates(boolean noiseInd, double noise){ //Presmetka na Xs i Ys, noiseInd = true ako ima noise
- distanceFromAnchors = new ArrayList<Double>();
- points = new ArrayList<Node>();
- innerPoints = new ArrayList<Node>();
- Random rand = new Random();
- //[dist - r%*dist, dist + r%*dist]
- for(int i = 0; i < nearbyAnchors.size(); i++)
- {
- double Xa = nearbyAnchors.get(i).X;
- double Ya = nearbyAnchors.get(i).Y;
- double Za = nearbyAnchors.get(i).Z;
- double dist = distance(X,Y,Z,Xa, Ya,Za);
- if(noiseInd) //Ako ima noise
- {
- double n = noise * rand.nextDouble();
- double s = -1;
- if(rand.nextBoolean())
- s = 1;
- n*=s;
- dist += (dist/100.0)*n;
- }
- distanceFromAnchors.add(dist);
- }
- double radius1 = Double.MAX_VALUE; //prvo najmalo rastojanie
- double radius2 = Double.MAX_VALUE; // vtoro najmalo rastojanie
- double radius3 = Double.MAX_VALUE; //treto najmalo rastojanie
- int j1 = -1, j2 = -1, j3 = -1; //Indeksi na trite anchors
- for(int i = 0; i < distanceFromAnchors.size();i++){
- if(distanceFromAnchors.get(i) < radius1)
- {
- radius3 = radius2;
- radius2 = radius1;
- radius1 = distanceFromAnchors.get(i);
- j3 = j2;
- j2 = j1;
- j1 = i;
- }
- else if(distanceFromAnchors.get(i) < radius2)
- {
- radius3 = radius2;
- radius2 = distanceFromAnchors.get(i);
- j3 = j2;
- j2 = i;
- }
- else if(distanceFromAnchors.get(i) < radius3){
- radius3 = distanceFromAnchors.get(i);
- j3 = i;
- }
- }
- return true;
- }
- public void trilateration(Node p1, Node p2, Node p3){
- }
- public double distance(double x1, double y1, double z1, double x2, double y2, double z2){ //Evklidovo rastojanie
- return Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1));
- }
- public double sqr(double a) { //kvadrat
- return a * a;
- }
- public double norm(Node a) {
- return Math.sqrt(sqr(a.X) + sqr(a.Y) + sqr(a.Z));
- }
- public double dot(Node a, Node b) {
- return a.X * b.X + a.Y * b.Y + a.Z * b.Z;
- }
- public Node vector_subtract(Node a, Node b) {
- Node node = new Node(a.X-b.X, a.Y-b.Y, a.Z-b.Z, false);
- return node;
- }
- public Node vector_add(Node a, Node b) {
- Node node = new Node(a.X+b.X, a.Y+b.Y, a.Z+b.Z, false);
- return node;
- }
- public Node vector_divide(Node a, double b) {
- Node node = new Node(a.X/b, a.Y/b, a.Z/b,false);
- return node;
- }
- public Node vector_multiply(Node a, double b) {
- Node node = new Node(a.X*b, a.Y*b, a.Z*b,false);
- return node;
- }
- public Node vector_cross(Node a, Node b) {
- Node node = new Node(a.Y * b.Z - a.Z * b.Y,a.Z * b.X - a.X * b.Z,a.X * b.Y - a.Y * b.X,false);
- return node;
- }
- public void allIntersectingPoints(Node n1, Node n2, Node n3){ //Za site presecni tocki na tri kruznici so centri vo n1, n2, n3
- List<Circle> circles = new ArrayList<Circle>();
- circles.add(new Circle(n1, distance(n1.X, n1.Y, n1.Z, n2.X, n2.Y,n2.Z)));
- circles.add(new Circle(n2, distance(n2.X, n2.Y, n2.Z, n3.X, n3.Y,n3.Z)));
- circles.add(new Circle(n3, distance(n3.X, n3.Y, n3.Z, n1.X, n1.Y,n1.Z)));
- intersectingPoints(circles.get(0), circles.get(1));
- intersectingPoints(circles.get(1), circles.get(2));
- intersectingPoints(circles.get(2), circles.get(0));
- for(int i = 0; i < points.size(); i++)
- {
- if(isContainedInCircles(points.get(i), circles))
- innerPoints.add(points.get(i));
- }
- }
- public void intersectingPoints(Circle c1, Circle c2){ // Naogja presecni tocki na dve kruznici
- Node p1 = c1.center;
- Node p2 = c2.center;
- double r1 = c1.radius;
- double r2 = c2.radius;
- double dist = distance(p1.X, p1.Y, p1.Z,p2.X, p2.Y,p2.Z);
- if(dist >= (r1+r2) || dist <= Math.abs(r1-r2))
- return;
- double a = (r1*r1-r2*r2 + dist*dist)/(2*dist);
- double h = Math.sqrt(r1*r1 - a*a);
- double x0 = p1.X + a*(p2.X - p1.X)/dist;
- double y0 = p1.Y + a*(p2.Y - p1.Y)/dist;
- double rx = -(p2.Y - p1.Y) * (h/dist);
- double ry = -(p2.X - p1.X) * (h / dist);
- Node n1 = new Node(x0+rx,y0-ry,false);
- Node n2 = new Node(x0-rx,y0+ry,false);
- points.add(n1);
- points.add(n2);
- }
- public boolean getCoordinates(){ //Presmetka na koordinati na teziste
- if(innerPoints.size() == 0)
- return false;
- double Xn = 0, Yn = 0;
- for(int i = 0; i < innerPoints.size(); i++)
- {
- Xn+=innerPoints.get(i).X;
- Yn+=innerPoints.get(i).Y;
- }
- Xn/=innerPoints.size();
- Yn/=innerPoints.size();
- Xs = Xn;
- Ys = Yn;
- return true;
- }
- public boolean isContainedInCircles(Node node, List<Circle> circles){ //Dali tockata pripagja na site kruznici
- for(int i = 0; i < circles.size(); i++)
- {
- if(distance(node.X, node.Y,node.Z,circles.get(i).center.X,circles.get(i).center.Y,circles.get(i).center.Z) > circles.get(i).radius)
- return false;
- }
- return true;
- }
- public String printCoordinates(){
- if(!anchor)
- return String.format("X: %-8.02f Y: %-8.02f Xs i Ys ne moze da se presmetaat\n", X,Y);
- else if(original)
- return String.format("X: %-8.02f Y: %-8.02f ---> Original anchor", X,Y);
- else
- return String.format("X: %-8.02f Y: %-8.02f Xs: %-8.02f Ys: %-8.02f\n", X,Y,Xs,Ys);
- }
- public String toString(){
- if(original)
- return String.format("X: %-8.02f Y: %-8.02f -> Original anchor\n", X,Y);
- else
- return String.format("X: %-8.2f Y: %.2f\n", X,Y);
- }
- }
- class WSN{
- List<Node> nodes; //lista od site jazli
- List<Node> anchors; //lista od anchors
- int N, anchorPer; //N: vkupen broj na jazli, anchorPer: procent na anchor jazli
- double R, L, noise, anchorNum; //L: dolzina na oblast, R: radio opseg, noise: sum na signal, anchorNum: broj na anchor jazli sto treba da se generiraat
- boolean anchor;
- public WSN(int N, int anchorPer, double R, double L, double noise) throws FileNotFoundException{
- nodes = new ArrayList<Node>();
- anchors = new ArrayList<Node>();
- this.N = N;
- this.L = L;
- this.R = R;
- this.noise = noise;
- this.anchorPer = anchorPer;
- anchor = false;
- Random rand = new Random();
- PrintWriter pw = new PrintWriter("F:/FINKI/VI semestar/Senzorski sistemi/Trilateration/anchorsCoordinates.txt");
- PrintWriter pw2 = new PrintWriter("F:/FINKI/VI semestar/Senzorski sistemi/Trilateration/nodesCoordinates.txt");
- int counter = 0; //counter za anchor jazli
- anchorNum = ((double)N/100)*anchorPer; //broj na anchor jazli sto treba da se generiraat
- for(int i = 0; i < N; i++){
- double x = L * rand.nextDouble();
- double y = L * rand.nextDouble();
- double z = L * rand.nextDouble();
- if(counter < anchorNum){
- anchor = true;
- counter++;
- }
- else
- anchor = false;
- Node node = new Node(x, y, z,anchor); //Generiranje na nov jazol i dodavanje vo listata
- nodes.add(node);
- if(anchor)
- {
- anchors.add(node);
- pw.append(String.format("%.2f %.2f\n", node.X,node.Y));
- }
- else
- {
- pw2.append(String.format("%.2f %.2f\n", node.X,node.Y));
- }
- }
- pw.close();
- pw2.close();
- }
- public double distance(double x1, double y1, double z1,double x2, double y2, double z2){ //Evklidovo rastojanie
- return Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1));
- }
- public void calculate(){
- boolean noiseInd = false; // (dali ima noise ili ne)
- if(noise != 0)
- noiseInd = true;
- this.addAnchors(); //Na pocetok, vo listite na sekoj jazol se dodavaat prvicnite anchor jazli (ako se vo radio opseg)
- int counter = 0;
- int prevCounter = -1;
- while(true){
- for(int i = 0; i < nodes.size();i++){
- if(!nodes.get(i).anchor && nodes.get(i).nearbyAnchors.size() >= 3){
- double tmp1 = nodes.get(i).Xs;
- double tmp2 = nodes.get(i).Ys;
- nodes.get(i).calculateCoordinates(noiseInd, noise);
- nodes.get(i).anchor = true; //Stom kje se presmetaat Xs i Ys, jazolot stanuva anchor
- if(tmp1!=nodes.get(i).Xs || tmp2!=nodes.get(i).Ys) //Ako ima nova presmetana vrednost za Xs ili Ys
- counter++;
- for(int j = 0; j < nodes.size(); j++)
- {
- if(j != i && !nodes.get(j).anchor){
- double dist = this.distance(nodes.get(i).X, nodes.get(i).Y, nodes.get(i).Z,nodes.get(j).X, nodes.get(j).Y,nodes.get(j).Z);
- if(dist<=R)
- nodes.get(j).nearbyAnchors.add(nodes.get(i)); //Noviot anchor se dodava kaj drugite jazli (ako e vo nivniot radio opseg)
- }
- }
- }
- }
- if(counter == prevCounter)
- break;
- else
- {
- prevCounter = counter;
- }
- }
- }
- public void addAnchors(){
- //Za sekoj jazol sto ne e anchor se naogjaat anchor jazlite sto se vo radio opsegot
- for(int i = 0; i < nodes.size(); i++)
- {
- if(!nodes.get(i).original)
- {
- for(int j = 0; j < anchors.size(); j++)
- {
- double dist = this.distance(nodes.get(i).X, nodes.get(i).Y, nodes.get(i).Z,anchors.get(j).X, anchors.get(j).Y,nodes.get(i).Z);
- if(dist<=R)
- nodes.get(i).nearbyAnchors.add(anchors.get(j));
- }
- }
- }
- }
- public double avgNeighbors(){
- double avg = 0;
- for(int i = 0; i < nodes.size(); i++)
- {
- avg+=nodes.get(i).nearbyAnchors.size();
- }
- avg/=nodes.size();
- return avg;
- }
- public double calculateError(){ //Presmetka na greska
- double error = 0;
- for(int i = 0; i < nodes.size(); i++)
- {
- if(nodes.get(i).anchor && !nodes.get(i).original)
- {
- double err = distance(nodes.get(i).X, nodes.get(i).Y,nodes.get(i).Z, nodes.get(i).Xs, nodes.get(i).Ys,nodes.get(i).Zs);
- error+=err;
- }
- }
- //error/=(N-anchorNum)*1.0;
- error /= N*1.0;
- //System.out.println(String.format("ERROR: %.3f", error));
- double error_per = (error/R)*100.0;
- //System.out.println(String.format("ERROR PERCENTAGE: %.3f", error_per));
- return error_per;
- }
- public String toString(){
- StringBuilder sb = new StringBuilder();
- sb.append("Wireless Sensor Network\n");
- for(int i = 0; i < nodes.size();i++)
- {
- sb.append(nodes.get(i).toString());
- }
- return sb.toString();
- }
- public void printCoordinates(){
- for(int i =0; i < nodes.size();i++)
- System.out.println(nodes.get(i).printCoordinates());
- }
- public void printDistance(){
- for(int i = 0; i < nodes.size(); i++)
- System.out.println(distance(nodes.get(i).X, nodes.get(i).Y, nodes.get(i).Z, nodes.get(i).Xs, nodes.get(i).Ys,nodes.get(i).Zs));
- }
- public void getCoordinatesForVisualization() throws FileNotFoundException{ //Gi zapisuva vo txt za crtanje
- PrintWriter pw1 = new PrintWriter("F:/FINKI/VI semestar/Senzorski sistemi/Trilateration/anchorsCoordinatesFinal.txt");
- PrintWriter pw2 = new PrintWriter("F:/FINKI/VI semestar/Senzorski sistemi/Trilateration/nodesCoordinatesFinal.txt");
- PrintWriter pw3 = new PrintWriter("F:/FINKI/VI semestar/Senzorski sistemi/Trilateration/unlocatedNodesCoordinatesFinal.txt");
- for(int i = 0; i < nodes.size();i++)
- {
- if(nodes.get(i).original)
- pw1.append(String.format("%.2f %.2f\n", nodes.get(i).X,nodes.get(i).Y));
- else if (nodes.get(i).anchor)
- pw2.append(String.format("%.2f %.2f\n", nodes.get(i).X,nodes.get(i).Y));
- else
- pw3.append(String.format("%.2f %.2f\n", nodes.get(i).X,nodes.get(i).Y));
- }
- pw1.close();
- pw2.close();
- pw3.close();
- }
- }
- class Circle{
- Node center;
- double radius;
- public Circle(Node center, double radius){
- this.center = center;
- this.radius = radius;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement