/// <summary> /// A rasterizer. /// </summary> /// <remarks> /// For more info see http://www.codeproject.com/KB/graphics/bresenham_revisited.aspx /// </remarks> /// <param name="begin">The index of the begin of the line.</param> /// <param name="end">The index of the begin of the line.</param> /// <param name="dem">A list of dems.</param> /// <returns>A list with the rastered indexs</returns> private static List<Index> rasterizeLineOrig(Index begin, Index end, double scaleFactor) { List<Index> retIndex = new List<Index>(); double totalDistance = Math.Sqrt(Math.Pow((begin.getRow() - end.getRow()), 2) + Math.Pow((begin.getCol() - end.getCol()), 2)); double totalHeight = (double)(end.getAlt() - begin.getAlt())/scaleFactor; double angle = Math.Atan2(totalHeight,totalDistance); int deltaX = end.getCol() - begin.getCol(); int deltaY = (int)Math.Abs(begin.getRow() - end.getRow()); int error = (int)(deltaX / 2.0); int yStep = 1; if (end.getRow() < begin.getRow()) yStep = -1; else if (end.getRow() == begin.getRow()) yStep = 0; int indX = begin.getCol(); int indY = begin.getRow(); retIndex.Add(begin); while (indX < end.getCol()) { indX++; error -= deltaY; if (error < 0) { indY += yStep; error += deltaX; } double d = Math.Sqrt(Math.Pow((begin.getRow() - indY), 2) + Math.Pow((begin.getCol() - indX), 2)); double alt = (double)begin.getAlt() + d * Math.Tan(angle) * scaleFactor; retIndex.Add(new Index(indY, indX, alt)); } return retIndex; }
/// <summary> /// Main Function. Decide which routine is going to rasterize line /// </summary> /// <param name="begin">The index of the begin of the line.</param> /// <param name="end">The index of the begin of the line.</param> /// <param name="dem">A list of dems.</param> /// <returns>A list with the rastered indexs</returns> public static List<Index> rasterizeLine(Index begin, Index end, double scaleFactor) { if (Math.Abs(end.getRow() - begin.getRow()) < Math.Abs(end.getCol() - begin.getCol())) { if (end.getCol() >= begin.getCol()) return rasterizeLineOrig(begin, end, scaleFactor); else return rasterizeLineReverseOrig(begin, end, scaleFactor); } else { if (end.getRow() >= begin.getRow()) return rasterizeLineSteep(begin, end, scaleFactor); else return rasterizeLineReverseSteep(begin, end, scaleFactor); } }
//--------------------------------------------------------------------- /// <summary> /// Returns a <see cref="Points.Point"/> representing the highest /// waypoint in the current <see cref="Dem"/> /// </summary> /// <returns> /// A <see cref="Points.Point"/>. /// </returns> //--------------------------------------------------------------------- public Point getMaxAltitude() { Index index = new Index(); double altitude = double.MinValue; for(int i = 0; i <rows;i++) { for (int j = 0; j < cols; j++) { if (altitude < this.altitude[i,j]) { altitude = this.altitude[i, j]; index = new Index(i, j, altitude); } } } return indexToPoint(index); }
//--------------------------------------------------------------------- /// <summary> /// Returns the correspoding waypoint from the specified indexs. /// </summary> /// <param name="index"> /// The specified indexs. /// </param> /// <returns> /// The corresponding waypoint. /// </returns> //--------------------------------------------------------------------- public abstract WgsPoint indexToPoint(Index index);
//--------------------------------------------------------------------- /// <summary> /// Return the terrain altitude from the specified indexs. /// </summary> /// <param name="index"> /// The specified indexs. /// </param> /// <returns> /// The terrain altitude. /// </returns> //--------------------------------------------------------------------- public virtual double getAltitudeFromIndex(Index index) { if (index.getCol() < cols && (index.getRow()) < rows && index.getCol() > -1 && index.getRow() > -1) return this.altitude[(index.getRow()),index.getCol()]; else return double.MaxValue; }
//--------------------------------------------------------------------- /// <summary> /// Return the terrain altitude from the specified indexs. /// </summary> /// <param name="index"> /// The specified indexs. /// </param> /// <returns> /// The terrain altitude. /// </returns> //--------------------------------------------------------------------- public override WgsPoint indexToPoint(Index index) { double utmY = this.bottomLeft.getUtmY() + this.cellSize * (this.rows - index.getRow()); double utmX = this.bottomLeft.getUtmX() + this.cellSize * index.getCol(); if (this.bottomLeft.getLatitude() < 0) return new WgsPoint(utmX, utmY, index.getAlt(), this.bottomLeft.getTimeZone(), 'S'); else return new WgsPoint(utmX, utmY, index.getAlt(), this.bottomLeft.getTimeZone(), 'N'); }
//--------------------------------------------------------------------- /// <summary> /// Returns an altitude submatrix delimited by the specified waypoints. /// </summary> /// <param name="bottomLeft"> /// Bottom left corner waypoint. /// </param> /// <param name="topRight"> /// Top right corner waypoint. /// </param> /// <returns> /// The altiude submatrix. /// </returns> //--------------------------------------------------------------------- public override Dem getSelection(Point bottomLeft, Point topRight) { bottomLeft = bottomLeft.toWgs(); topRight = topRight.toWgs(); Index indBottomLeft = new Index(pointToIndex(bottomLeft).getRow() + 2, pointToIndex(bottomLeft).getCol() - 2); Index indTopRight = new Index(pointToIndex(topRight).getRow() - 2, pointToIndex(topRight).getCol() + 2); int selectRows = (int)(indBottomLeft.getRow() - indTopRight.getRow() + 1); int selectCols = (int)(indTopRight.getCol() - indBottomLeft.getCol() + 1); double[,] selection = new double[selectRows, selectCols]; for (int i = indTopRight.getRow(); i < (indTopRight.getRow() + selectRows); i++) { for (int j = indBottomLeft.getCol(); j < (indBottomLeft.getCol() + selectCols); j++) { selection [i - indTopRight.getRow(), j - indBottomLeft.getCol()] = this.altitude[i - 1, j]; } } return new Srtm30(selectRows, selectCols, (WgsPoint)this.indexToPoint(indBottomLeft), selection); }
//--------------------------------------------------------------------- /// <summary> /// Returns the correspoding waypoint from the specified indexs. /// </summary> /// <param name="index"> /// The specified indexs. /// </param> /// <returns> /// The corresponding waypoint. /// </returns> //--------------------------------------------------------------------- public override WgsPoint indexToPoint(Index index) { double latitude = this.bottomLeft.getLatitude() + this.cellSize * (this.rows - index.getRow()); double longitude = this.bottomLeft.getLongitude() + this.cellSize * index.getCol(); return new WgsPoint(latitude, longitude, index.getAlt()); }