/**
* Copyright (C) 2011 Aarhus University
*
* This software is provided under the MIT-license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*
*
* @author Rasmus W. Lauritsen ([email protected], [email protected], [email protected])
* @date 2011-12-28
*
*/
package dk.au.eng;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Panel;
import java.util.HashMap;
import java.util.Map;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import org.overture.interpreter.values.IntegerValue;
import org.overture.interpreter.values.NumericValue;
import org.overture.interpreter.values.SeqValue;
import org.overture.interpreter.values.Value;
import org.overture.interpreter.values.VoidValue;
public class Radar extends Panel {
private static final long serialVersionUID = 8425314445103581406L;
private static class FlyingObject {
int longtitude;
int latitude;
int showlong;
int showlat;
String transponder;
boolean isShown;
public FlyingObject(int lo, int la, int al, String transponder)
{
this.longtitude = lo;
this.latitude = la;
this.transponder = transponder;
}
}
private int scanAngle;
private int step = 5;
private int scanWidth = 20; // degrees
private Font font;
private Graphics pen;
private boolean isShowing;
private Map<String,FlyingObject> fos = new HashMap<String,FlyingObject>();
private long scanTime = 20; // Time to make a step in ms
private JFrame window;
private ImageIcon background;
private void addFo(FlyingObject fo)
{
synchronized(fos)
{
fos.put(fo.transponder,fo);
}
}
// Display a dot and transponder code for o if it is inside scan cone.
private void putObject(FlyingObject o, Graphics pen)
{
if (isInScanCone(o.longtitude, o.latitude))
{
// The flying oject o, just entered the scan range
if (!o.isShown)
{
o.isShown=true;
o.showlat = o.latitude;
o.showlong = o.longtitude;
}
int[] coords = radarCrdToScreenCrd(o.showlong, o.showlat);
Color c = pen.getColor();
pen.setColor(Color.BLUE);
pen.fillOval(coords[0], coords[1], 8, 8);
pen.setColor(Color.WHITE);
pen.drawString(o.transponder, coords[0]+10, coords[1]);
pen.setColor(c);
}
else
o.isShown = false;
}
private static int[] radarCrdToScreenCrd(int x, int y)
{
int[] res = new int[2];
res[0] = x + 200;res[1] = 200-y;
return res;
}
private void putLineOnRadar(int x, int y, int x1, int y1, Color c)
{
if (pen != null)
{
Color oc = pen.getColor();
pen.setColor(c);
int[] startCrds = radarCrdToScreenCrd(x, y);
int[] stopCrds = radarCrdToScreenCrd(x1, y1);
pen.drawLine(startCrds[0],startCrds[1],stopCrds[0],stopCrds[1]);
pen.setColor(oc);
}
}
private static double radianToDegrees(double rad) { return 57.2957795 * rad; }
public static int crdToAngle(int x, int y)
{
double len = Math.sqrt(Math.pow(x,2) + Math.pow(y,2));
double xAngle = Math.acos( x / len );
// Q1 => No extra xAngle is the answer
// Q2 => No extra xAngle is the answer
// Q3 => x is negative and hence xAngle is 90 degrees off
// on the vertical axis xAngle is 180 off
// Q4 => No extra xAngle is 270 degrees off
double extra = y < 0 ? 360 - radianToDegrees(xAngle) : radianToDegrees(xAngle);
return (int)(Math.round(extra));
}
private boolean isInScanCone(int x, int y)
{
int fromAngle = scanAngle - scanWidth;
int toAngle = scanAngle;
return crdToAngle(x, y) > fromAngle && crdToAngle(x, y) < toAngle;
}
public Radar()
{
background = new ImageIcon(Radar.class.getResource("radardisc.jpg"));
this.setBackground(Color.BLACK);
font = new Font("Helvetica",Font.BOLD,12);
setPreferredSize(new Dimension(400, 400));
scanAngle = (90 % step == 0 ) ? 1 : 0;
this.window = makeWindow(this);
}
public void stepScan()
{
scanAngle += step;
scanAngle = scanAngle % 360;
this.repaint();
}
@Override
public void paint(Graphics arg0) {
drawRadarDisc(arg0);
}
private void drawRadarDisc(final Graphics pen)
{
if (SwingUtilities.isEventDispatchThread())
{
if ( (this.pen=pen) != null)
{
pen.setFont(font);
//pen.setColor(new Color(0x3b,0x82,0x0c));
// Draw disc
pen.drawImage(background.getImage(),0,0,400,400,background.getImageObserver());
// Draw center dot
pen.setColor(Color.BLACK);
pen.fillOval(195,195,10,10);
// Draw rings
for(int d = 10; d < 200;d+=10)
pen.drawOval(200-d, 200-d, 2*d, 2*d);
// Draw the flying objects in this radar
synchronized(fos)
{
for(FlyingObject fo : fos.values())
putObject(fo, pen);
}
// Draw the scan line
putLineOnRadar(0, 0,
(int)(200*Math.cos(degreesToRadians(scanAngle))),
(int)(200*Math.sin(degreesToRadians(scanAngle))), Color.YELLOW);
}
return;
}
// Not the dispatcher thread lets delegate this invocation
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
drawRadarDisc(pen);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
private static JFrame makeWindow(Component content)
{
JFrame window = new JFrame();
window.getContentPane().add(content);
window.setSize(content.getPreferredSize());
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setTitle("VDM Radar");
window.pack();
return window;
}
private static double degreesToRadians(int degree)
{
return (44.0 * degree) / 2520.0;
}
//------------------------------------------------------
// VDM Interface
//------------------------------------------------------
// -- AddFlyingObject: int * int * int * seq of char ==> ()
public Value AddFlyingObject(Value longtitude, Value latitude, Value altitude, Value transponder)
{
synchronized(this.fos)
{
IntegerValue iv = (IntegerValue)longtitude;
IntegerValue la = (IntegerValue)latitude;
FlyingObject fo = new FlyingObject( (int)iv.value, (int)la.value, 10, transponder.toString());
this.addFo(fo);
return new VoidValue();
}
}
// -- RemFlyingObject: seq of char ==> ()
public Value RemFlyingObject(Value transponder)
{
synchronized(this.fos)
{
fos.remove(transponder);
return new VoidValue();
}
}
// -- UpdateFlyingObject: seq of char * int * int ==> ()
public Value UpdateFlyingObject(Value transponder, Value longtitude, Value latitude)
{
int lon = (int)((IntegerValue)longtitude).value;
int lat = (int)((IntegerValue)latitude).value;
synchronized(this.fos)
{
FlyingObject o = fos.get(transponder);
if (o != null)
{
o.longtitude = lon;
o.latitude = lat;
}
return new VoidValue();
}
}
// -- SetStepSize: int ==> ()
public Value SetStepSize(Value newStep)
{
this.step = (int)((IntegerValue)newStep).value;
return new VoidValue();
}
// -- StepRadar: () ==> ()
public Value StepRadar()
{
// If the window is not shown yet, show it!
if (!isShowing)
{
isShowing = true;
(window).setVisible(true);
}
// step the radar
this.stepScan();
// wait a bit to simulate it takes time to scan
try {
Thread.sleep(scanTime);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return new VoidValue();
}
// -- SetScanWidth: int ==> ()
public Value SetScanWidth(Value width)
{
this.scanWidth = (int)((IntegerValue)width).value;
return new VoidValue();
}
// -- SetScanTime: int ==> ()
public Value SetScanTime(Value scanTime)
{
this.scanTime = (int)((IntegerValue)scanTime).value;
return new VoidValue();
}
// -- SetWindowPosition: int * int ==> ()
public Value SetWindowPosition(Value ix, Value iy)
{
int x = (int)((IntegerValue)ix).value;
int y = (int)((IntegerValue)iy).value;
this.window.setLocation(x, y);
return new VoidValue();
}
// -- SetTitle: seq of char ==> ()
public Value SetTitle(Value v)
{
window.setTitle(v.toString());
return new VoidValue();
}
// -- SetScanAngle: int ==> ()
public Value SetScanAngle(Value v)
{
scanAngle = (int)((IntegerValue)v).value;
return new VoidValue();
}
// -- static ToCharSeq: token ==> seq of char
public static Value ToCharSeq(Value v)
{
if (v != null)
{
System.out.println(v.getClass());
if (v instanceof NumericValue)
{
NumericValue nv = (NumericValue)v;
return new SeqValue("Number:"+Double.toString(nv.value));
}
if (v != null)
return new SeqValue(v.toString());
}
else System.out.println("V is null, Why the face.");
return new SeqValue();
}
public static void main(String[] args)
{
Radar r = new Radar();
r.StepRadar();
}
}
¤ Dauer der Verarbeitung: 0.26 Sekunden
(vorverarbeitet)
¤
|
Haftungshinweis
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.
|