diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/data/filter/Approximator.java b/MPChartLib/src/main/java/com/github/mikephil/charting/data/filter/Approximator.java
deleted file mode 100644
index 70170f2e81..0000000000
--- a/MPChartLib/src/main/java/com/github/mikephil/charting/data/filter/Approximator.java
+++ /dev/null
@@ -1,99 +0,0 @@
-
-package com.github.mikephil.charting.data.filter;
-
-import android.annotation.TargetApi;
-import android.os.Build;
-
-import java.util.Arrays;
-
-/**
- * Implemented according to Wiki-Pseudocode {@link}
- * ...�Douglas�Peucker_algorithm
- *
- * @author Philipp Baldauf & Phliipp Jahoda
- */
-public class Approximator {
-
- @TargetApi(Build.VERSION_CODES.GINGERBREAD)
- public float[] reduceWithDouglasPeucker(float[] points, float tolerance) {
-
- int greatestIndex = 0;
- float greatestDistance = 0f;
-
- Line line = new Line(points[0], points[1], points[points.length - 2], points[points.length - 1]);
-
- for (int i = 2; i < points.length - 2; i += 2) {
-
- float distance = line.distance(points[i], points[i + 1]);
-
- if (distance > greatestDistance) {
- greatestDistance = distance;
- greatestIndex = i;
- }
- }
-
- if (greatestDistance > tolerance) {
-
- float[] reduced1 = reduceWithDouglasPeucker(Arrays.copyOfRange(points, 0, greatestIndex + 2), tolerance);
- float[] reduced2 = reduceWithDouglasPeucker(Arrays.copyOfRange(points, greatestIndex, points.length),
- tolerance);
-
- float[] result1 = reduced1;
- float[] result2 = Arrays.copyOfRange(reduced2, 2, reduced2.length);
-
- return concat(result1, result2);
- } else {
- return line.getPoints();
- }
- }
-
- /**
- * Combine arrays.
- */
- float[] concat(float[]... arrays) {
- int length = 0;
- for (float[] array : arrays) {
- length += array.length;
- }
- float[] result = new float[length];
- int pos = 0;
- for (float[] array : arrays) {
- for (float element : array) {
- result[pos] = element;
- pos++;
- }
- }
- return result;
- }
-
- private class Line {
-
- private final float[] points;
-
- private final float sxey;
- private final float exsy;
-
- private final float dx;
- private final float dy;
-
- private final float length;
-
- public Line(float x1, float y1, float x2, float y2) {
- dx = x1 - x2;
- dy = y1 - y2;
- sxey = x1 * y2;
- exsy = x2 * y1;
- length = (float) Math.sqrt(dx * dx + dy * dy);
-
- points = new float[]{x1, y1, x2, y2};
- }
-
- public float distance(float x, float y) {
- return Math.abs(dy * x - dx * y + sxey - exsy) / length;
- }
-
- public float[] getPoints() {
- return points;
- }
- }
-}
diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/data/filter/Approximator.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/data/filter/Approximator.kt
new file mode 100644
index 0000000000..32f58bc9bb
--- /dev/null
+++ b/MPChartLib/src/main/java/com/github/mikephil/charting/data/filter/Approximator.kt
@@ -0,0 +1,80 @@
+package com.github.mikephil.charting.data.filter
+
+import android.annotation.TargetApi
+import android.os.Build
+import kotlin.math.abs
+import kotlin.math.sqrt
+
+/**
+ * Implemented according to Wiki-Pseudocode []
+ * [...](http://en.wikipedia.org/wiki/Ramer)�Douglas�Peucker_algorithm
+ */
+class Approximator {
+ @TargetApi(Build.VERSION_CODES.GINGERBREAD)
+ fun reduceWithDouglasPeucker(points: FloatArray, tolerance: Float): FloatArray {
+ var greatestIndex = 0
+ var greatestDistance = 0f
+
+ val line = Line(points[0], points[1], points[points.size - 2], points[points.size - 1])
+
+ var i = 2
+ while (i < points.size - 2) {
+ val distance = line.distance(points[i], points[i + 1])
+
+ if (distance > greatestDistance) {
+ greatestDistance = distance
+ greatestIndex = i
+ }
+ i += 2
+ }
+
+ if (greatestDistance > tolerance) {
+ val reduced1 = reduceWithDouglasPeucker(points.copyOfRange(0, greatestIndex + 2), tolerance)
+ val reduced2 = reduceWithDouglasPeucker(
+ points.copyOfRange(greatestIndex, points.size),
+ tolerance
+ )
+
+ val result2 = reduced2.copyOfRange(2, reduced2.size)
+
+ return concat(reduced1, result2)
+ } else {
+ return line.points
+ }
+ }
+
+ /**
+ * Combine arrays.
+ */
+ fun concat(vararg arrays: FloatArray): FloatArray {
+ var length = 0
+ for (array in arrays) {
+ length += array.size
+ }
+ val result = FloatArray(length)
+ var pos = 0
+ for (array in arrays) {
+ for (element in array) {
+ result[pos] = element
+ pos++
+ }
+ }
+ return result
+ }
+
+ private class Line(x1: Float, y1: Float, x2: Float, y2: Float) {
+ val points: FloatArray = floatArrayOf(x1, y1, x2, y2)
+
+ private val sxeY: Float = x1 * y2
+ private val exsY: Float = x2 * y1
+
+ private val dx: Float = x1 - x2
+ private val dy: Float = y1 - y2
+
+ private val length: Float = sqrt((dx * dx + dy * dy).toDouble()).toFloat()
+
+ fun distance(x: Float, y: Float): Float {
+ return abs(dy * x - dx * y + sxeY - exsY) / length
+ }
+ }
+}
diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/data/filter/ApproximatorN.java b/MPChartLib/src/main/java/com/github/mikephil/charting/data/filter/ApproximatorN.java
deleted file mode 100644
index 9351341c76..0000000000
--- a/MPChartLib/src/main/java/com/github/mikephil/charting/data/filter/ApproximatorN.java
+++ /dev/null
@@ -1,146 +0,0 @@
-
-package com.github.mikephil.charting.data.filter;
-
-import java.util.ArrayList;
-
-/**
- * Implemented according to modified Douglas Peucker {@link}
- * http://psimpl.sourceforge.net/douglas-peucker.html
- */
-public class ApproximatorN
-{
- public float[] reduceWithDouglasPeucker(float[] points, float resultCount) {
-
- int pointCount = points.length / 2;
-
- // if a shape has 2 or less points it cannot be reduced
- if (resultCount <= 2 || resultCount >= pointCount)
- return points;
-
- boolean[] keep = new boolean[pointCount];
-
- // first and last always stay
- keep[0] = true;
- keep[pointCount - 1] = true;
-
- int currentStoredPoints = 2;
-
- ArrayList queue = new ArrayList<>();
- Line line = new Line(0, pointCount - 1, points);
- queue.add(line);
-
- do {
- line = queue.remove(queue.size() - 1);
-
- // store the key
- keep[line.index] = true;
-
- // check point count tolerance
- currentStoredPoints += 1;
-
- if (currentStoredPoints == resultCount)
- break;
-
- // split the polyline at the key and recurse
- Line left = new Line(line.start, line.index, points);
- if (left.index > 0) {
- int insertionIndex = insertionIndex(left, queue);
- queue.add(insertionIndex, left);
- }
-
- Line right = new Line(line.index, line.end, points);
- if (right.index > 0) {
- int insertionIndex = insertionIndex(right, queue);
- queue.add(insertionIndex, right);
- }
- } while (queue.isEmpty());
-
- float[] reducedEntries = new float[currentStoredPoints * 2];
-
- for (int i = 0, i2 = 0, r2 = 0; i < currentStoredPoints; i++, r2 += 2) {
- if (keep[i]) {
- reducedEntries[i2++] = points[r2];
- reducedEntries[i2++] = points[r2 + 1];
- }
- }
-
- return reducedEntries;
- }
-
- private static float distanceToLine(
- float ptX, float ptY, float[]
- fromLinePoint1, float[] fromLinePoint2) {
- float dx = fromLinePoint2[0] - fromLinePoint1[0];
- float dy = fromLinePoint2[1] - fromLinePoint1[1];
-
- float dividend = Math.abs(
- dy * ptX -
- dx * ptY -
- fromLinePoint1[0] * fromLinePoint2[1] +
- fromLinePoint2[0] * fromLinePoint1[1]);
- double divisor = Math.sqrt(dx * dx + dy * dy);
-
- return (float)(dividend / divisor);
- }
-
- private static class Line {
- int start;
- int end;
-
- float distance = 0;
- int index = 0;
-
- Line(int start, int end, float[] points) {
- this.start = start;
- this.end = end;
-
- float[] startPoint = new float[]{points[start * 2], points[start * 2 + 1]};
- float[] endPoint = new float[]{points[end * 2], points[end * 2 + 1]};
-
- if (end <= start + 1) return;
-
- for (int i = start + 1, i2 = i * 2; i < end; i++, i2 += 2) {
- float distance = distanceToLine(
- points[i2], points[i2 + 1],
- startPoint, endPoint);
-
- if (distance > this.distance) {
- this.index = i;
- this.distance = distance;
- }
- }
- }
-
- boolean equals(final Line rhs) {
- return (start == rhs.start) && (end == rhs.end) && index == rhs.index;
- }
-
- boolean lessThan(final Line rhs) {
- return distance < rhs.distance;
- }
- }
-
- private static int insertionIndex(Line line, ArrayList queue) {
- int min = 0;
- int max = queue.size();
-
- while (!queue.isEmpty()) {
- int midIndex = min + (max - min) / 2;
- Line midLine = queue.get(midIndex);
-
- if (midLine.equals(line)) {
- return midIndex;
- }
- else if (line.lessThan(midLine)) {
- // perform search in left half
- max = midIndex;
- }
- else {
- // perform search in right half
- min = midIndex + 1;
- }
- }
-
- return min;
- }
-}
diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/data/filter/ApproximatorN.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/data/filter/ApproximatorN.kt
new file mode 100644
index 0000000000..390203445b
--- /dev/null
+++ b/MPChartLib/src/main/java/com/github/mikephil/charting/data/filter/ApproximatorN.kt
@@ -0,0 +1,146 @@
+package com.github.mikephil.charting.data.filter
+
+import kotlin.math.abs
+import kotlin.math.sqrt
+
+/**
+ * Implemented according to modified Douglas Peucker []
+ * [...](http://psimpl.sourceforge.net/douglas-peucker.html)
+ */
+class ApproximatorN {
+ fun reduceWithDouglasPeucker(points: FloatArray, resultCount: Float): FloatArray {
+ val pointCount = points.size / 2
+
+ // if a shape has 2 or less points it cannot be reduced
+ if (resultCount <= 2 || resultCount >= pointCount) return points
+
+ val keep = BooleanArray(pointCount)
+
+ // first and last always stay
+ keep[0] = true
+ keep[pointCount - 1] = true
+
+ var currentStoredPoints = 2
+
+ val queue = ArrayList()
+ var line = Line(0, pointCount - 1, points)
+ queue.add(line)
+
+ do {
+ line = queue.removeAt(queue.size - 1)
+
+ // store the key
+ keep[line.index] = true
+
+ // check point count tolerance
+ currentStoredPoints += 1
+
+ if (currentStoredPoints.toFloat() == resultCount) break
+
+ // split the polyline at the key and recurse
+ val left = Line(line.start, line.index, points)
+ if (left.index > 0) {
+ val insertionIndex: Int = insertionIndex(left, queue)
+ queue.add(insertionIndex, left)
+ }
+
+ val right = Line(line.index, line.end, points)
+ if (right.index > 0) {
+ val insertionIndex: Int = insertionIndex(right, queue)
+ queue.add(insertionIndex, right)
+ }
+ } while (queue.isEmpty())
+
+ val reducedEntries = FloatArray(currentStoredPoints * 2)
+
+ var i = 0
+ var i2 = 0
+ var r2 = 0
+ while (i < currentStoredPoints) {
+ if (keep[i]) {
+ reducedEntries[i2++] = points[r2]
+ reducedEntries[i2++] = points[r2 + 1]
+ }
+ i++
+ r2 += 2
+ }
+
+ return reducedEntries
+ }
+
+ private class Line(var start: Int, var end: Int, points: FloatArray) {
+ var distance: Float = 0f
+ var index: Int = 0
+
+ init {
+ val startPoint = floatArrayOf(points[start * 2], points[start * 2 + 1])
+ val endPoint = floatArrayOf(points[end * 2], points[end * 2 + 1])
+
+ if (end > start + 1) {
+
+ var i = start + 1
+ var i2 = i * 2
+ while (i < end) {
+ val distance: Float = distanceToLine(
+ points[i2], points[i2 + 1],
+ startPoint, endPoint
+ )
+
+ if (distance > this.distance) {
+ this.index = i
+ this.distance = distance
+ }
+ i++
+ i2 += 2
+ }
+ }
+ }
+
+ fun equals(rhs: Line): Boolean {
+ return (start == rhs.start) && (end == rhs.end) && index == rhs.index
+ }
+
+ fun lessThan(rhs: Line): Boolean {
+ return distance < rhs.distance
+ }
+ }
+
+ companion object {
+ private fun distanceToLine(
+ ptX: Float, ptY: Float, fromLinePoint1: FloatArray, fromLinePoint2: FloatArray
+ ): Float {
+ val dx = fromLinePoint2[0] - fromLinePoint1[0]
+ val dy = fromLinePoint2[1] - fromLinePoint1[1]
+
+ val dividend = abs(
+ dy * ptX - dx * ptY - fromLinePoint1[0] * fromLinePoint2[1] +
+ fromLinePoint2[0] * fromLinePoint1[1]
+ )
+ val divisor = sqrt((dx * dx + dy * dy).toDouble())
+
+ return (dividend / divisor).toFloat()
+ }
+
+ private fun insertionIndex(line: Line, queue: ArrayList): Int {
+ var min = 0
+ var max = queue.size
+
+ while (!queue.isEmpty()) {
+ val midIndex = min + (max - min) / 2
+ val midLine = queue.get(midIndex)
+
+ if (midLine.equals(line)) {
+ return midIndex
+ } else if (line.lessThan(midLine)) {
+ // perform search in left half
+ max = midIndex
+ } else {
+ // perform search in right half
+ min = midIndex + 1
+ }
+ }
+
+ return min
+ }
+ }
+}