From b367942a1e8449e0cd6045afaedd0bab050be958 Mon Sep 17 00:00:00 2001 From: stepan <stepan.sindelar@oracle.com> Date: Tue, 4 Apr 2017 14:03:01 +0200 Subject: [PATCH] FastR Grid: implement 'bounds' versions of rectangle, points, and circle --- .../r/library/fastrGrid/EdgeDetection.java | 60 ++++++++++++- .../fastrGrid/FastRGridExternalLookup.java | 8 ++ .../r/library/fastrGrid/GridUtils.java | 5 ++ .../truffle/r/library/fastrGrid/LCircle.java | 4 + .../r/library/fastrGrid/LCircleBounds.java | 85 +++++++++++++++++++ .../r/library/fastrGrid/LLocnBounds.java | 83 ++++++++++++++++++ .../truffle/r/library/fastrGrid/LRect.java | 6 +- .../r/library/fastrGrid/LRectBounds.java | 81 ++++++++++++++++++ .../truffle/r/library/fastrGrid/Size.java | 4 + .../r/library/fastrGrid/TransformMatrix.java | 25 ++++++ .../truffle/r/library/fastrGrid/fastrGrid.R | 9 ++ mx.fastr/copyrights/overrides | 3 + 12 files changed, 369 insertions(+), 4 deletions(-) create mode 100644 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LCircleBounds.java create mode 100644 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LLocnBounds.java create mode 100644 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LRectBounds.java diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/EdgeDetection.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/EdgeDetection.java index b9d4070415..b78840d401 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/EdgeDetection.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/EdgeDetection.java @@ -21,6 +21,9 @@ import static com.oracle.truffle.r.runtime.nmath.TOMS708.fabs; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.RDoubleVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; /** * Contains static method related to edge detection for bounds calculations. @@ -106,9 +109,9 @@ final class EdgeDetection { } } else { /* Intersect with top/bottom */ if (sinTheta > 0) { /* Top */ - return new Point(ymax, xm + dy / tanTheta); + return new Point(xm + dy / tanTheta, ymax); } else { /* Bottom */ - return new Point(ymin, xm - dy / tanTheta); + return new Point(xm - dy / tanTheta, ymin); } } } @@ -200,6 +203,25 @@ final class EdgeDetection { return new Point(xm + ua * (x2 - xm), ym + ua * (y2 - ym)); } + public static Point hullEdge(GridContext ctx, double[] xx, double[] yy, double theta) { + RDoubleVector xVec = RDataFactory.createDoubleVector(xx, RDataFactory.COMPLETE_VECTOR); + RDoubleVector yVec = RDataFactory.createDoubleVector(yy, RDataFactory.COMPLETE_VECTOR); + Object hullObj = ctx.evalInternalRFunction("chullWrapper", xVec, yVec); + RAbstractIntVector hull = GridUtils.asIntVector(hullObj); + double[] newXX = new double[hull.getLength()]; + double[] newYY = new double[hull.getLength()]; + for (int i = 0; i < hull.getLength(); i++) { + newXX[i] = xx[hull.getDataAt(i) - 1]; + newYY[i] = yy[hull.getDataAt(i) - 1]; + } + return polygonEdge(newXX, newYY, newXX.length, theta); + } + + public static Point circleEdge(Point loc, double radius, double theta) { + double angle = theta / 180 * Math.PI; + return new Point(loc.x + radius * Math.cos(angle), loc.y + radius * Math.sin(angle)); + } + /** * An arbitrarily-oriented rectangle. The vertices are assumed to be in order going * anticlockwise around the rectangle. @@ -220,4 +242,38 @@ final class EdgeDetection { edgesIntersect(this.x[3], this.x[0], this.y[3], this.y[0], r2); } } + + /** + * Represents min and max value for X and Y coordinates and provides convenient methods to + * update them. + */ + public static final class Bounds { + public double minX = Double.MAX_VALUE; + public double maxX = Double.MIN_VALUE; + public double minY = Double.MAX_VALUE; + public double maxY = Double.MIN_VALUE; + + public void update(Point p) { + updateX(p.x); + updateY(p.y); + } + + public void updateX(double... values) { + minX = GridUtils.fmin(minX, values); + maxX = GridUtils.fmax(maxX, values); + } + + public void updateY(double... values) { + minY = GridUtils.fmin(minY, values); + maxY = GridUtils.fmax(maxY, values); + } + + public double getWidth() { + return maxX - minX; + } + + public double getHeight() { + return maxY - minY; + } + } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/FastRGridExternalLookup.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/FastRGridExternalLookup.java index 80d6a41600..1292153015 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/FastRGridExternalLookup.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/FastRGridExternalLookup.java @@ -120,6 +120,14 @@ public final class FastRGridExternalLookup { case "L_points": return LPoints.create(); + // Bounds primitive: + case "L_rectBounds": + return LRectBounds.create(); + case "L_locnBounds": + return LLocnBounds.create(); + case "L_circleBounds": + return LCircleBounds.create(); + // Simple grid state access case "L_getGPar": return new GridStateGetNode(GridState::getGpar); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridUtils.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridUtils.java index 8784637eb9..ebb3a04377 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridUtils.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridUtils.java @@ -20,6 +20,7 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RStringVector; @@ -82,6 +83,10 @@ final class GridUtils { return result; } + static RDoubleVector createDoubleVector(double... values) { + return RDataFactory.createDoubleVector(values, RDataFactory.COMPLETE_VECTOR); + } + static boolean hasRClass(RAttributable obj, String clazz) { RStringVector classAttr = obj.getClassAttr(); if (classAttr == null) { diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LCircle.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LCircle.java index 07ff0d4e40..537905c612 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LCircle.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LCircle.java @@ -31,6 +31,10 @@ public abstract class LCircle extends RExternalBuiltinNode.Arg3 { static { Casts casts = new Casts(LCircle.class); + addCircleCasts(casts); + } + + static void addCircleCasts(Casts casts) { casts.arg(0).mustBe(abstractVectorValue()); casts.arg(1).mustBe(abstractVectorValue()); casts.arg(2).mustBe(abstractVectorValue()); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LCircleBounds.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LCircleBounds.java new file mode 100644 index 0000000000..3b18079922 --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LCircleBounds.java @@ -0,0 +1,85 @@ +/* + * This material is distributed under the GNU General Public License + * Version 2. You may review the terms of this license at + * http://www.gnu.org/licenses/gpl-2.0.html + * + * Copyright (C) 2001-3 Paul Murrell + * Copyright (c) 1998-2013, The R Core Team + * Copyright (c) 2017, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.library.fastrGrid; + +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue; + +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.library.fastrGrid.EdgeDetection.Bounds; +import com.oracle.truffle.r.library.fastrGrid.Unit.UnitConversionContext; +import com.oracle.truffle.r.library.fastrGrid.ViewPortTransform.GetViewPortTransformNode; +import com.oracle.truffle.r.library.fastrGrid.device.GridDevice; +import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; +import com.oracle.truffle.r.runtime.data.RList; +import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.nmath.RMath; + +public abstract class LCircleBounds extends RExternalBuiltinNode.Arg4 { + @Child private Unit.UnitToInchesNode unitToInches = Unit.createToInchesNode(); + @Child private Unit.UnitLengthNode unitLength = Unit.createLengthNode(); + @Child private GetViewPortTransformNode getViewPortTransform = new GetViewPortTransformNode(); + + static { + Casts casts = new Casts(LCircleBounds.class); + LCircle.addCircleCasts(casts); + casts.arg(3).mustBe(numericValue()).asDoubleVector().findFirst(); + } + + public static LCircleBounds create() { + return LCircleBoundsNodeGen.create(); + } + + @Specialization + @TruffleBoundary + Object doCircle(RAbstractVector xVec, RAbstractVector yVec, RAbstractVector radiusVec, double theta) { + GridContext ctx = GridContext.getContext(); + GridDevice dev = ctx.getCurrentDevice(); + + RList currentVP = ctx.getGridState().getViewPort(); + GPar gpar = GPar.create(ctx.getGridState().getGpar()); + ViewPortTransform vpTransform = getViewPortTransform.execute(currentVP, dev); + ViewPortContext vpContext = ViewPortContext.fromViewPort(currentVP); + UnitConversionContext conversionCtx = new UnitConversionContext(vpTransform.size, vpContext, dev, gpar); + + int length = GridUtils.maxLength(unitLength, xVec, yVec, radiusVec); + Bounds bounds = new Bounds(); + int count = 0; + Point loc = null; // we remember the last position and radius + double radius = -1; + for (int i = 0; i < length; i++) { + Size radiusSizes = Size.fromUnits(unitToInches, radiusVec, radiusVec, i, conversionCtx); + radius = RMath.fmin2(radiusSizes.getWidth(), radiusSizes.getHeight()); + loc = Point.fromUnits(unitToInches, xVec, yVec, i, conversionCtx); + if (loc.isFinite() && Double.isFinite(radius)) { + bounds.updateX(loc.x - radius, loc.x + radius); + bounds.updateY(loc.y - radius, loc.y + radius); + count++; + } + } + + if (count == 0) { + return RNull.instance; + } + Point result; + assert loc != null; + if (count == 1) { + result = EdgeDetection.circleEdge(loc, radius, theta); + } else { + result = EdgeDetection.rectEdge(bounds.minX, bounds.minY, bounds.maxX, bounds.maxY, theta); + } + + double scale = ctx.getGridState().getScale(); + return GridUtils.createDoubleVector(result.x / scale, result.y / scale, bounds.getWidth() / scale, bounds.getHeight() / scale); + } +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LLocnBounds.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LLocnBounds.java new file mode 100644 index 0000000000..cd63a6165e --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LLocnBounds.java @@ -0,0 +1,83 @@ +/* + * This material is distributed under the GNU General Public License + * Version 2. You may review the terms of this license at + * http://www.gnu.org/licenses/gpl-2.0.html + * + * Copyright (C) 2001-3 Paul Murrell + * Copyright (c) 1998-2013, The R Core Team + * Copyright (c) 2017, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.library.fastrGrid; + +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.abstractVectorValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue; + +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.library.fastrGrid.EdgeDetection.Bounds; +import com.oracle.truffle.r.library.fastrGrid.Unit.UnitConversionContext; +import com.oracle.truffle.r.library.fastrGrid.ViewPortTransform.GetViewPortTransformNode; +import com.oracle.truffle.r.library.fastrGrid.device.GridDevice; +import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; +import com.oracle.truffle.r.runtime.data.RList; +import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.model.RAbstractVector; + +public abstract class LLocnBounds extends RExternalBuiltinNode.Arg3 { + @Child private Unit.UnitToInchesNode unitToInches = Unit.createToInchesNode(); + @Child private Unit.UnitLengthNode unitLength = Unit.createLengthNode(); + @Child private GetViewPortTransformNode getViewPortTransform = new GetViewPortTransformNode(); + + static { + Casts casts = new Casts(LLocnBounds.class); + casts.arg(0).mustBe(abstractVectorValue()); + casts.arg(1).mustBe(abstractVectorValue()); + casts.arg(2).mustBe(numericValue()).asDoubleVector().findFirst(); + } + + public static LLocnBounds create() { + return LLocnBoundsNodeGen.create(); + } + + @Specialization + @TruffleBoundary + Object doBounds(RAbstractVector xVec, RAbstractVector yVec, double theta) { + GridContext ctx = GridContext.getContext(); + GridDevice dev = ctx.getCurrentDevice(); + + RList currentVP = ctx.getGridState().getViewPort(); + GPar gpar = GPar.create(ctx.getGridState().getGpar()); + ViewPortTransform vpTransform = getViewPortTransform.execute(currentVP, dev); + ViewPortContext vpContext = ViewPortContext.fromViewPort(currentVP); + UnitConversionContext conversionCtx = new UnitConversionContext(vpTransform.size, vpContext, dev, gpar); + + int length = Math.max(Unit.getLength(xVec), Unit.getLength(yVec)); + if (length == 0) { + return RNull.instance; + } + + double[] xx = new double[length]; + double[] yy = new double[length]; + Bounds bounds = new Bounds(); + int count = 0; + for (int i = 0; i < length; i++) { + Point loc = Point.fromUnits(unitToInches, xVec, yVec, i, conversionCtx); + xx[i] = loc.x; + yy[i] = loc.y; + if (loc.isFinite()) { + bounds.update(loc); + count++; + } + } + + if (count == 0) { + return RNull.instance; + } + + Point edge = EdgeDetection.hullEdge(ctx, xx, yy, theta); + double scale = ctx.getGridState().getScale(); + return GridUtils.createDoubleVector(edge.x / scale, edge.y / scale, bounds.getWidth() / scale, bounds.getHeight() / scale); + } +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LRect.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LRect.java index 8fc3969d15..2edc48e95a 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LRect.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LRect.java @@ -33,6 +33,10 @@ public abstract class LRect extends RExternalBuiltinNode.Arg6 { static { Casts casts = new Casts(LRect.class); + addRectCasts(casts); + } + + static void addRectCasts(Casts casts) { casts.arg(0).mustBe(abstractVectorValue()); casts.arg(1).mustBe(abstractVectorValue()); casts.arg(2).mustBe(abstractVectorValue()); @@ -60,8 +64,6 @@ public abstract class LRect extends RExternalBuiltinNode.Arg6 { int length = GridUtils.maxLength(unitLength, xVec, yVec, wVec, hVec); for (int i = 0; i < length; i++) { Size size = Size.fromUnits(unitToInches, wVec, hVec, i, conversionCtx); - // Note: once this is factored to drawing/recording: this transformation is necessary - // only for drawing Point origLoc = Point.fromUnits(unitToInches, xVec, yVec, i, conversionCtx); Point transLoc = TransformMatrix.transLocation(origLoc, vpTransform.transform); Point loc = transLoc.justify(size, getDataAtMod(hjust, i), getDataAtMod(vjust, i)); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LRectBounds.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LRectBounds.java new file mode 100644 index 0000000000..133bee5ddc --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LRectBounds.java @@ -0,0 +1,81 @@ +/* + * This material is distributed under the GNU General Public License + * Version 2. You may review the terms of this license at + * http://www.gnu.org/licenses/gpl-2.0.html + * + * Copyright (C) 2001-3 Paul Murrell + * Copyright (c) 1998-2013, The R Core Team + * Copyright (c) 2017, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.library.fastrGrid; + +import static com.oracle.truffle.r.library.fastrGrid.EdgeDetection.rectEdge; +import static com.oracle.truffle.r.library.fastrGrid.GridUtils.getDataAtMod; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue; + +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.library.fastrGrid.EdgeDetection.Bounds; +import com.oracle.truffle.r.library.fastrGrid.Unit.UnitConversionContext; +import com.oracle.truffle.r.library.fastrGrid.ViewPortTransform.GetViewPortTransformNode; +import com.oracle.truffle.r.library.fastrGrid.device.GridDevice; +import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; +import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.RList; +import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractVector; + +public abstract class LRectBounds extends RExternalBuiltinNode.Arg7 { + @Child private Unit.UnitToInchesNode unitToInches = Unit.createToInchesNode(); + @Child private Unit.UnitLengthNode unitLength = Unit.createLengthNode(); + @Child private GetViewPortTransformNode getViewPortTransform = new GetViewPortTransformNode(); + + static { + Casts casts = new Casts(LRectBounds.class); + LRect.addRectCasts(casts); + casts.arg(6).mustBe(numericValue()).asDoubleVector().findFirst(); + } + + public static LRectBounds create() { + return LRectBoundsNodeGen.create(); + } + + @Specialization + @TruffleBoundary + Object execute(RAbstractVector xVec, RAbstractVector yVec, RAbstractVector wVec, RAbstractVector hVec, RAbstractDoubleVector hjust, RAbstractDoubleVector vjust, double theta) { + GridContext ctx = GridContext.getContext(); + GridDevice dev = ctx.getCurrentDevice(); + + RList currentVP = ctx.getGridState().getViewPort(); + GPar gpar = GPar.create(ctx.getGridState().getGpar()); + ViewPortTransform vpTransform = getViewPortTransform.execute(currentVP, dev); + ViewPortContext vpContext = ViewPortContext.fromViewPort(currentVP); + UnitConversionContext conversionCtx = new UnitConversionContext(vpTransform.size, vpContext, dev, gpar); + + int length = GridUtils.maxLength(unitLength, xVec, yVec, wVec, hVec); + Bounds bounds = new Bounds(); + int nrect = 0; + for (int i = 0; i < length; i++) { + Size size = Size.fromUnits(unitToInches, wVec, hVec, i, conversionCtx); + Point origLoc = Point.fromUnits(unitToInches, xVec, yVec, i, conversionCtx); + // just calculate the bounds, no transformation necessary + Point loc = origLoc.justify(size, getDataAtMod(hjust, i), getDataAtMod(vjust, i)); + if (size.isFinite() && loc.isFinite()) { + bounds.updateX(loc.x, loc.x + size.getWidth()); + bounds.updateY(loc.y, loc.y + size.getHeight()); + nrect++; + } + } + + if (nrect == 0) { + return RNull.instance; + } + + Point edge = rectEdge(bounds.minX, bounds.minY, bounds.maxX, bounds.maxY, theta); + double scale = ctx.getGridState().getScale(); + return RDataFactory.createDoubleVector(new double[]{edge.x / scale, edge.y / scale, bounds.getWidth() / scale, bounds.getHeight() / scale}, RDataFactory.COMPLETE_VECTOR); + } +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/Size.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/Size.java index c428af3df6..5ab5ed6373 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/Size.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/Size.java @@ -48,4 +48,8 @@ public final class Size { public double getHeight() { return height; } + + public boolean isFinite() { + return Double.isFinite(width) && Double.isFinite(height); + } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/TransformMatrix.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/TransformMatrix.java index e1051c98a4..28ed32b803 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/TransformMatrix.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/TransformMatrix.java @@ -13,6 +13,11 @@ package com.oracle.truffle.r.library.fastrGrid; import static com.oracle.truffle.r.runtime.nmath.MathConstants.M_PI; +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RError.Message; + +// transcribed from matrix.c + /** * Operations on transformation (3x3) matrices. */ @@ -115,4 +120,24 @@ final class TransformMatrix { } return res; } + + public static double[][] inversion(double[][] t) { + double det = t[0][0] * (t[2][2] * t[1][1] - t[2][1] * t[1][2]) - + t[1][0] * (t[2][2] * t[0][1] - t[2][1] * t[0][2]) + + t[2][0] * (t[1][2] * t[0][1] - t[1][1] * t[0][2]); + if (det == 0) { + throw RError.error(RError.NO_CALLER, Message.GENERIC, "singular transformation matrix"); + } + double[][] invt = new double[3][3]; + invt[0][0] = 1 / det * (t[2][2] * t[1][1] - t[2][1] * t[1][2]); + invt[0][1] = -1 / det * (t[2][2] * t[0][1] - t[2][1] * t[0][2]); + invt[0][2] = 1 / det * (t[1][2] * t[0][1] - t[1][1] * t[0][2]); + invt[1][0] = -1 / det * (t[2][2] * t[1][0] - t[2][0] * t[1][2]); + invt[1][1] = 1 / det * (t[2][2] * t[0][0] - t[2][0] * t[0][2]); + invt[1][2] = -1 / det * (t[1][2] * t[0][0] - t[1][0] * t[0][2]); + invt[2][0] = 1 / det * (t[2][1] * t[1][0] - t[2][0] * t[1][1]); + invt[2][1] = -1 / det * (t[2][1] * t[0][0] - t[2][0] * t[0][1]); + invt[2][2] = 1 / det * (t[1][1] * t[0][0] - t[1][0] * t[0][1]); + return invt; + } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/fastrGrid.R b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/fastrGrid.R index 4614a924ef..70cf79d4d7 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/fastrGrid.R +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/fastrGrid.R @@ -15,6 +15,15 @@ # logic to R. Some functions implement whole externals, like L_downvppath, some implement coherent # parts of the logic and the rest is in Java. + +# chull from grDevices package is used in EdgeDetection.java +# Note: chull calls to native function, which we may consider +# porting or calling directly in the future. +chullWrapper <- function(x, y) { + library(grDevices) + grDevices:::chull(x, y) +} + # Returns list with elements [[1]] - depth, zero if not found, [[2]] - the viewport, NULL if not found # We are searching for child "name" in "pvp", if the "path" is not missing, # then also pathMatch(path, currPath) must hold. diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides index 2298d75da7..a72c103a9a 100644 --- a/mx.fastr/copyrights/overrides +++ b/mx.fastr/copyrights/overrides @@ -744,6 +744,9 @@ com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/p com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/Deriv.java,gnu_r_gentleman_ihaka2.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/DerivVisitor.java,gnu_r_gentleman_ihaka2.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LRect.java,gnu_r_murrel_core.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LRectBounds.java,gnu_r_murrel_core.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LCircleBounds.java,gnu_r_murrel_core.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LLocnBounds.java,gnu_r_murrel_core.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/DrawArrowsNode.java,gnu_r_murrel_core.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LPoints.java,gnu_r_murrel_core.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/GridState.java,gnu_r_murrel_core.copyright -- GitLab