@ -1,7 +1,5 @@
package visualiser.model ;
import javafx.scene.Node ;
import javafx.scene.image.Image ;
import javafx.scene.paint.Color ;
import javafx.scene.paint.Paint ;
@ -12,7 +10,6 @@ import shared.model.GPSCoordinate;
import shared.model.Mark ;
import shared.model.RaceClock ;
import java.time.Duration ;
import java.util.List ;
/ * *
@ -29,23 +26,13 @@ import java.util.List;
* /
public class ResizableRaceCanvas extends ResizableCanvas {
/ * *
* The RaceMap used for converting GPSCoordinates to GraphCoordinates .
* /
private RaceMap map ;
/ * *
* The race we read data from and draw .
* /
private VisualiserRace visualiserRace ;
/ * *
* The background of the race .
* We render the background whenever the race boundary changes , or the screen size changes .
* /
private RaceMap map ; // for converting GPSCoordinates to GraphCoordinates
private VisualiserRace visualiserRace ; // draw data read from this race
private Image background ;
private Image sailsRight = new Image ( "/images/sailsRight.png" ) ;
private Image sailsLeft = new Image ( "/images/sailsLeft.png" ) ;
// annotations
private boolean annoName = true ;
private boolean annoAbbrev = true ;
private boolean annoSpeed = true ;
@ -53,15 +40,12 @@ public class ResizableRaceCanvas extends ResizableCanvas {
private boolean annoEstTime = true ;
private boolean annoTimeSinceLastMark = true ;
/ * *
* Constructs a { @link ResizableRaceCanvas } using a given { @link VisualiserRace } .
* @param visualiserRace The race that data is read from in order to be drawn .
* /
public ResizableRaceCanvas ( VisualiserRace visualiserRace ) {
super ( ) ;
this . visualiserRace = visualiserRace ;
RaceDataSource raceData = visualiserRace . getRaceDataSource ( ) ;
@ -72,14 +56,9 @@ public class ResizableRaceCanvas extends ResizableCanvas {
double long2 = raceData . getMapBottomRight ( ) . getLongitude ( ) ;
this . map = new RaceMap (
lat1 , long1 , lat2 , long2 ,
( int ) getWidth ( ) , ( int ) getHeight ( ) ) ;
lat1 , long1 , lat2 , long2 , ( int ) getWidth ( ) , ( int ) getHeight ( ) ) ;
}
/ * *
* Toggle name display in annotation
* /
@ -119,11 +98,9 @@ public class ResizableRaceCanvas extends ResizableCanvas {
annoSpeed = ! annoSpeed ;
}
/ * *
* Rotates things on the canvas Note : this must be called in between gc . save ( ) and gc . restore ( ) else they will rotate everything
* Rotates things displayed on the canvas . Note : this must be called in
* between gc . save ( ) and gc . restore ( ) else they will rotate everything
*
* @param degrees Bearing degrees to rotate .
* @param px Pivot point x of rotation .
@ -134,8 +111,6 @@ public class ResizableRaceCanvas extends ResizableCanvas {
gc . setTransform ( r . getMxx ( ) , r . getMyx ( ) , r . getMxy ( ) , r . getMyy ( ) , r . getTx ( ) , r . getTy ( ) ) ;
}
/ * *
* Draws a circle with a given diameter , centred on a given graph coordinate .
* @param center The center coordinate of the circle .
@ -147,8 +122,8 @@ public class ResizableRaceCanvas extends ResizableCanvas {
gc . fillOval (
center . getX ( ) - ( diameter / 2 ) ,
center . getY ( ) - ( diameter / 2 ) ,
diameter , diameter ) ;
diameter , diameter
) ;
}
/ * *
@ -163,7 +138,6 @@ public class ResizableRaceCanvas extends ResizableCanvas {
gc . setStroke ( paint ) ;
gc . setFill ( paint ) ;
double endPointDiameter = 6 ;
//Draw first end-point.
@ -177,8 +151,8 @@ public class ResizableRaceCanvas extends ResizableCanvas {
graphCoordinateA . getX ( ) ,
graphCoordinateA . getY ( ) ,
graphCoordinateB . getX ( ) ,
graphCoordinateB . getY ( ) ) ;
graphCoordinateB . getY ( )
) ;
}
/ * *
@ -198,7 +172,6 @@ public class ResizableRaceCanvas extends ResizableCanvas {
drawCircle ( graphCoordinate , pointDiameter ) ;
}
/ * *
* Display given name and speed of boat at a graph coordinate
*
@ -214,7 +187,6 @@ public class ResizableRaceCanvas extends ResizableCanvas {
//The text to draw. Built during the function.
String text = "" ;
//Draw name if annotation is enabled.
if ( annoName ) {
text + = String . format ( "%s " , name ) ;
@ -240,7 +212,6 @@ public class ResizableRaceCanvas extends ResizableCanvas {
text + = timeSinceLastMark ;
}
//Offset by 20 pixels horizontally.
long xCoord = coordinate . getX ( ) + 20 ;
long yCoord = coordinate . getY ( ) ;
@ -259,41 +230,36 @@ public class ResizableRaceCanvas extends ResizableCanvas {
gc . fillText ( text , xCoord , yCoord ) ;
}
/ * *
* Draws the label for a given boat . Includes name , abbreviation , speed , time since mark , and time to next mark .
* @param boat The boat to draw text for .
* /
private void drawBoatText ( VisualiserBoat boat ) {
drawText (
boat . getName ( ) ,
boat . getCountry ( ) ,
boat . getCurrentSpeed ( ) ,
this . map . convertGPS ( boat . getCurrentPosition ( ) ) ,
boat . getTimeToNextMarkFormatted ( this . visualiserRace . getRaceClock ( ) . getCurrentTime ( ) ) ,
boat . getTimeSinceLastMarkFormatted ( this . visualiserRace . getRaceClock ( ) . getCurrentTime ( ) ) ) ;
boat . getTimeSinceLastMarkFormatted ( this . visualiserRace . getRaceClock ( ) . getCurrentTime ( ) )
) ;
}
/ * *
* Draws all of the boats on the canvas .
* /
private void drawBoats ( ) {
for ( VisualiserBoat boat : visualiserRace . getBoats ( ) ) {
//Draw the boat.
drawBoat ( boat ) ;
//Draw track.
drawTrack ( boat ) ;
//Only draw wake if they are currently racing.
if ( boat . getStatus ( ) = = BoatStatusEnum . RACING ) {
drawWake ( boat ) ;
}
//Draw the boat.
drawBoat ( boat ) ;
//If the race hasn't started, we set the time since last mark to the current time, to ensure we don't start counting until the race actually starts.
if ( ( boat . getStatus ( ) ! = BoatStatusEnum . RACING ) & & ( boat . getStatus ( ) = = BoatStatusEnum . FINISHED ) ) {
@ -302,16 +268,9 @@ public class ResizableRaceCanvas extends ResizableCanvas {
//Draw boat label.
drawBoatText ( boat ) ;
//Draw track.
drawTrack ( boat ) ;
}
}
/ * *
* Draws a given boat on the canvas .
* @param boat The boat to draw .
@ -346,28 +305,66 @@ public class ResizableRaceCanvas extends ResizableCanvas {
gc . fillPolygon ( x , y , 3 ) ;
gc . restore ( ) ;
// TODO: update with current players boat
if ( boat . getSourceID ( ) = = 125 ) {
drawSails ( boat ) ;
}
}
}
/ * *
* Draws sails for a given boat on the canvas . Sail position is
* determined by the boats heading and the current wind direction
* according to the "points of sail" .
* @param boat boat to display sails for
* /
private void drawSails ( VisualiserBoat boat ) {
GraphCoordinate boatPos =
this . map . convertGPS ( boat . getCurrentPosition ( ) ) ;
double xPos = boatPos . getX ( ) ; // x pos of sail (on boat)
double yPos = boatPos . getY ( ) - 6 ; // y pos of sail (on boat)
double boatBearing = boat . getBearing ( ) . degrees ( ) ;
double windDirection = visualiserRace . getWindDirection ( ) . degrees ( ) ;
windDirection = 0 ; // set to 0 for now - will be removed
double sailRotateAngle ; // required rotation for correct sail display
Image sailImage ;
gc . save ( ) ;
// right half of points of sail
if ( boatBearing < 180 ) {
sailImage = sailsRight ;
sailRotateAngle = boatBearing * 0.5 ; // math
xPos - = 1 ; // right align to boat edge on canvas
// System.out.println("right side -- boat: " + boatBearing +
// "|| rotate: " + sailRotateAngle);
}
// left half of points of sail
else {
sailImage = sailsLeft ;
sailRotateAngle = - ( 360 - boatBearing ) * 0.5 ; // math
xPos - = 5 ; // left align to boat edge on canvas
// System.out.println("left side -- boat: " + boatBearing +
// "|| rotate: " + sailRotateAngle);
}
// rotate sails based on boats current heading
rotate ( sailRotateAngle , boatPos . getX ( ) , boatPos . getY ( ) ) ;
gc . drawImage ( sailImage , xPos , yPos ) ;
gc . restore ( ) ;
}
/ * *
* Draws the wake for a given boat .
* @param boat Boat to draw wake for .
* /
private void drawWake ( VisualiserBoat boat ) {
//Calculate either end of wake line.
// Calculate either end of wake line.
GraphCoordinate wakeFrom = this . map . convertGPS ( boat . getCurrentPosition ( ) ) ;
GraphCoordinate wakeTo = this . map . convertGPS ( boat . getWake ( ) ) ;
//Draw.
drawLine ( wakeFrom , wakeTo , boat . getColor ( ) ) ;
}
/ * *
* Draws all of the { @link Mark } s on the canvas .
* /
@ -377,46 +374,30 @@ public class ResizableRaceCanvas extends ResizableCanvas {
}
}
/ * *
* Draws a given mark on the canvas .
* @param mark The mark to draw .
* /
private void drawMark ( Mark mark ) {
//Calculate screen position.
GraphCoordinate mark1 = this . map . convertGPS ( mark . getPosition ( ) ) ;
//Draw.
drawPoint ( mark1 , Color . LIMEGREEN ) ;
GraphCoordinate markToDraw = this . map . convertGPS ( mark . getPosition ( ) ) ;
drawPoint ( markToDraw , Color . LIMEGREEN ) ;
}
/ * *
* Draws the Race Map .
* Called when the canvas is resized .
* /
public void draw ( ) {
//Clear canvas.
clear ( ) ;
clear ( ) ; // clear previous canvas
//Update our RaceMap using new canvas size.
this . map . setWidth ( ( int ) getWidth ( ) ) ;
this . map . setHeight ( ( int ) getHeight ( ) ) ;
//Redraw the boundary.
redrawBoundaryImage ( ) ;
//Draw the race.
drawRace ( ) ;
}
/ * *
* Clears the canvas .
* /
@ -424,19 +405,16 @@ public class ResizableRaceCanvas extends ResizableCanvas {
gc . clearRect ( 0 , 0 , getWidth ( ) , getHeight ( ) ) ;
}
/ * *
* Draws the race boundary , and saves the image to { @link # background } .
* You should call { @link # clear ( ) } before calling this .
* /
private void redrawBoundaryImage ( ) {
//Prepare to draw.
gc . setLineWidth ( 1 ) ;
gc . setFill ( Color . AQUA ) ;
gc . drawImage ( new Image ( getClass ( ) . getClassLoader ( ) . getResourceAsStream ( "images/WaterBackground.png" ) ) , 0 , 0 ) ;
//Calculate the screen coordinates of the boundary.
List < GPSCoordinate > boundary = this . visualiserRace . getBoundary ( ) ;
double [ ] xpoints = new double [ boundary . size ( ) ] ;
@ -456,7 +434,6 @@ public class ResizableRaceCanvas extends ResizableCanvas {
//Render boundary to image.
this . background = snapshot ( null , null ) ;
}
/ * *
@ -464,23 +441,14 @@ public class ResizableRaceCanvas extends ResizableCanvas {
* Called once per frame , and on canvas resize .
* /
public void drawRace ( ) {
gc . setLineWidth ( 2 ) ;
clear ( ) ; // clear the previous canvas
clear ( ) ;
//Race boundary.
drawBoundary ( ) ;
//Boats.
drawBoats ( ) ;
//Marks.
drawMarks ( ) ;
}
/ * *
* Draws the race boundary image onto the canvas .
* See { @link # background } .
@ -489,13 +457,9 @@ public class ResizableRaceCanvas extends ResizableCanvas {
gc . drawImage ( this . background , 0 , 0 ) ;
}
/ * *
* Draws all track points for a given boat . Colour is set by boat , opacity by track point .
* This checks if { @link # annoPath } is enabled .
* Draws all track points for a given boat . Colour is set by boat , opacity
* by track point . This checks if { @link # annoPath } is enabled .
* @param boat The boat to draw tracks for .
* @see TrackPoint
* /
@ -517,9 +481,6 @@ public class ResizableRaceCanvas extends ResizableCanvas {
gc . fillOval ( scaledCoordinate . getX ( ) , scaledCoordinate . getY ( ) , point . getDiameter ( ) , point . getDiameter ( ) ) ;
}
}
}
}