2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2013 - Pedro Arthur dos S. Souza
4 * Copyright (C) 2013 - Caio Lucas dos S. Souza
6 * Copyright (C) 2012 - 2016 - Scilab Enterprises
8 * This file is hereby licensed under the terms of the GNU GPL v2.0,
9 * pursuant to article 5.3.4 of the CeCILL v.2.1.
10 * This file was originally licensed under the terms of the CeCILL v2.1,
11 * and continues to be available under such terms.
12 * For more information, see the COPYING file which you should have received
13 * along with this program.
17 package org.scilab.modules.gui.editor;
20 import org.scilab.modules.graphic_objects.graphicController.GraphicController;
21 import org.scilab.modules.graphic_objects.graphicObject.GraphicObject;
22 import org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties;
23 import org.scilab.modules.graphic_objects.CallGraphicController;
24 import org.scilab.modules.renderer.CallRenderer;
26 import org.scilab.modules.graphic_objects.axes.Axes;
27 import org.scilab.modules.renderer.JoGLView.axes.AxesDrawer;
28 import org.scilab.modules.renderer.JoGLView.DrawerVisitor;
29 import org.scilab.forge.scirenderer.tranformations.Vector3d;
31 import org.scilab.modules.graphic_objects.PolylineData;
32 import org.scilab.modules.graphic_objects.SurfaceData;
33 import org.scilab.modules.graphic_objects.ObjectData;
34 import org.scilab.modules.renderer.utils.CommonHandler;
35 import org.scilab.modules.renderer.utils.AxesHandler;
37 import java.lang.Math;
38 import java.util.List;
39 import java.util.LinkedList;
42 * GED Object picker for all Graphics Objects
45 public class GEDPicker {
47 private final Double delta = 7.0;
48 private Integer axesUID;
53 * Picker, given a figure and a click position in pixel coordinates
54 * it returns an array of objects picked
56 * @param figureUID Unique id from the figure object
57 * @param position Mouse click position in pixels
58 * @return Array of picked objects
60 public Integer[] pick(Integer figureUID, Integer[] position) {
63 boolean curObj = false;
65 axesUID = AxesHandler.clickedAxes(figureUID, position);
66 axes = AxesHandler.getAxesFromUid(axesUID);
69 return new Integer[] { figureUID };
71 List<Integer> ret = new LinkedList<Integer>();
72 AllObjs = getAllObjAsArray(axesUID);
74 for (int i = 0; i < AllObjs.length; i++) {
76 Integer type = (Integer)GraphicController.getController().getProperty(AllObjs[i], GraphicObjectProperties.__GO_TYPE__);
77 if (!CommonHandler.isVisible(AllObjs[i])) {
82 case GraphicObjectProperties.__GO_POLYLINE__:
83 curObj = getPolyline(AllObjs[i], position);
85 case GraphicObjectProperties.__GO_PLOT3D__:
86 case GraphicObjectProperties.__GO_GRAYPLOT__:
87 case GraphicObjectProperties.__GO_FAC3D__:
88 case GraphicObjectProperties.__GO_MATPLOT__:
89 curObj = getSurface(AllObjs[i], position);
91 case GraphicObjectProperties.__GO_LEGEND__:
92 curObj = getLegend(AllObjs[i], position);
94 case GraphicObjectProperties.__GO_LABEL__:
95 curObj = getLabel(AllObjs[i], position);
97 case GraphicObjectProperties.__GO_ARC__:
98 curObj = getArc(AllObjs[i], position);
100 case GraphicObjectProperties.__GO_CHAMP__:
101 curObj = getChamp(AllObjs[i], position);
103 case GraphicObjectProperties.__GO_FEC__:
104 curObj = getFec(AllObjs[i], position);
106 case GraphicObjectProperties.__GO_RECTANGLE__:
107 curObj = getRectangle(AllObjs[i], position);
109 case GraphicObjectProperties.__GO_SEGS__:
110 curObj = getSegs(AllObjs[i], position);
112 case GraphicObjectProperties.__GO_DATATIP__:
113 curObj = getDatatip(AllObjs[i], position);
115 case GraphicObjectProperties.__GO_COMPOUND__:
123 if (ret.size() > 0) {
124 return ret.toArray(new Integer[ret.size()]);
127 if (isInsideAxes(figureUID, position)) {
128 return new Integer[] { axesUID };
130 return new Integer[] { figureUID };
135 * Polyline picker, given a polyline object it checks if the click
138 * @param obj The given polyline object uid
139 * @param position Mouse click position in pixels
140 * @return true if picked the polyline otherwise returns false
142 boolean getPolyline(Integer obj, Integer[] position) {
144 double[] datax = (double[])PolylineData.getDataX(obj);
145 double[] datay = (double[])PolylineData.getDataY(obj);
146 double[] dataz = (double[])PolylineData.getDataZ(obj);
148 if (PolylineData.isXShiftSet(obj) != 0) {
149 double[] x_shift = (double[])PolylineData.getShiftX(obj);
150 for (int i = 0; i < datax.length; ++i) {
151 datax[i] += x_shift[i];
155 if (PolylineData.isYShiftSet(obj) != 0) {
156 double[] y_shift = (double[])PolylineData.getShiftY(obj);
157 for (int i = 0; i < datay.length; ++i) {
158 datay[i] += y_shift[i];
162 if (PolylineData.isZShiftSet(obj) != 0) {
163 double[] z_shift = (double[])PolylineData.getShiftZ(obj);
164 for (int i = 0; i < dataz.length; ++i) {
165 dataz[i] += z_shift[i];
169 datax = CommonHandler.toLogScale(datax, axes.getXAxisLogFlag());
170 datay = CommonHandler.toLogScale(datay, axes.getYAxisLogFlag());
171 dataz = CommonHandler.toLogScale(dataz, axes.getZAxisLogFlag());
174 double[] pos = {1.0 * position[0], 1.0 * position[1], 1.0};
175 double[] c2d = CallRenderer.get2dViewFromPixelCoordinates(axesUID, pos);
179 double[] c2d2 = CallRenderer.get2dViewFromPixelCoordinates(axesUID, pos);
181 double dx = Math.abs(c2d[0] - c2d2[0]);
182 double dy = Math.abs(c2d[1] - c2d2[1]);
184 if (AxesHandler.isZoomBoxEnabled(axesUID)) {
185 if (!AxesHandler.isInZoomBoxBounds(axesUID, c2d[0], c2d[1])) {
190 Double[] rotAngles = (Double[])GraphicController.getController().getProperty(axesUID, GraphicObjectProperties.__GO_ROTATION_ANGLES__);
191 boolean default2dView = (rotAngles[0] == 0.0 && rotAngles[1] == 270.0);
192 double[] oldPoint = new double[3];
194 if (CommonHandler.isLineEnabled(obj)) {
195 //System.out.println("lineEnable");
196 if (!default2dView) {
197 oldPoint = AxesDrawer.compute2dViewCoordinates(axes, new double[] { datax[0], datay[0], dataz[0] });
198 //System.out.println("NotDefault");
201 for (Integer i = 0; i < (datax.length - 1); ++i) {
202 if (!default2dView) {
203 double[] newPoint = AxesDrawer.compute2dViewCoordinates(axes, new double[] {datax[i + 1], datay[i + 1], dataz[i + 1]});
204 if (isInRange(oldPoint[0], newPoint[0], oldPoint[1], newPoint[1], c2d[0], c2d[1], dx, dy)) {
205 //System.out.println("in");
210 if (isInRange(datax[i], datax[i + 1], datay[i], datay[i + 1], c2d[0], c2d[1], dx, dy)) {
217 if (CommonHandler.isMarkEnabled(obj)) {
219 Integer markSize = CommonHandler.getMarkSize(obj);
220 Integer unit = CommonHandler.getMarkSizeUnit(obj);
222 int finalSize = (unit == 1) ? (8 + 2 * markSize) : markSize;
224 double deltax = Math.abs((dx / delta) * finalSize);
225 double deltay = Math.abs((dy / delta) * finalSize);
228 for (int i = 0; i < datax.length; ++i) {
229 if (!default2dView) {
230 double[] point = AxesDrawer.compute2dViewCoordinates(axes, new double[] {datax[i], datay[i], dataz[i]});
231 if ((Math.abs(point[0] - c2d[0]) <= deltax) && (Math.abs(point[1] - c2d[1]) <= deltay)) {
235 if ((Math.abs(datax[i] - c2d[0]) <= deltax) && (Math.abs(datay[i] - c2d[1]) <= deltay)) {
246 * Surface picker, given a plot3d/fac3d/grayplot/matplot object it checks if the click
249 * @param obj The given surface object uid
250 * @param position Mouse click position in pixels
251 * @return true if picked the surface otherwise returns false
253 boolean getSurface(Integer obj, Integer[] position) {
254 GraphicObject go = GraphicController.getController().getObjectFromId(obj);
255 Integer figure = go.getParentFrameOrFigure();
256 double[] mat = DrawerVisitor.getVisitor(figure).getAxesDrawer().getProjection(axesUID).getMatrix();
257 double[][] factors = axes.getScaleTranslateFactors();
259 Vector3d v0 = AxesDrawer.unProject(axes, new Vector3d(1.0f * position[0], 1.0f * position[1], 0.0));
260 Vector3d v1 = AxesDrawer.unProject(axes, new Vector3d(1.0f * position[0], 1.0f * position[1], 1.0));
261 v0 = new Vector3d((v0.getX() - factors[1][0]) / factors[0][0], (v0.getY() - factors[1][1]) / factors[0][1], (v0.getZ() - factors[1][2]) / factors[0][2]);
262 v1 = new Vector3d((v1.getX() - factors[1][0]) / factors[0][0], (v1.getY() - factors[1][1]) / factors[0][1], (v1.getZ() - factors[1][2]) / factors[0][2]);
264 Vector3d Dir = v0.minus(v1).getNormalized();
266 double curZ = SurfaceData.pickSurface(obj, v0.getX(), v0.getY(), v0.getZ(),
267 Dir.getX(), Dir.getY(), Dir.getZ(), mat[2], mat[6], mat[10], mat[14]);
275 * Legend picker, given a legend object it checks if the click
278 * @param obj The given legend object uid
279 * @param position Mouse click position in pixels
280 * @return true if picked the legend otherwise returns false
282 boolean getLegend(Integer obj, Integer[] position) {
283 Integer[] axesSize = {0, 0};
285 Double[] axesBounds = { 0., 0. }, dPosition = { 0., 0. }, legendPos = { 0., 0. }, legendBounds = { 0., 0., 0., 0. }, dimension = { 0., 0. };
287 GraphicObject go = GraphicController.getController().getObjectFromId(obj);
288 Integer figure = go.getParentFrameOrFigure();
289 axesSize = (Integer[])GraphicController.getController().getProperty(figure, GraphicObjectProperties.__GO_AXES_SIZE__);
290 axesBounds = (Double[])GraphicController.getController().getProperty(axesUID, GraphicObjectProperties.__GO_AXES_BOUNDS__);
291 legendPos = (Double[])GraphicController.getController().getProperty(obj, GraphicObjectProperties.__GO_POSITION__);
292 dPosition[0] = (position[0] - (axesBounds[0] * axesSize[0])) / (axesBounds[2] * axesSize[0]);
293 dPosition[1] = (position[1] - (axesBounds[1] * axesSize[1])) / (axesBounds[3] * axesSize[1]);
294 dimension = (Double[])GraphicController.getController().getProperty(obj, GraphicObjectProperties.__GO_SIZE__);
295 legendBounds[0] = legendPos[0];
296 legendBounds[1] = legendPos[1];
297 legendBounds[2] = legendPos[0] + dimension[0];
298 legendBounds[3] = legendPos[1] + dimension[1];
300 if (dPosition[0] >= legendBounds[0] && dPosition[0] <= legendBounds[2] && dPosition[1] >= legendBounds[1] && dPosition[1] <= legendBounds[3]) {
307 * Label picker, given a label object it checks if the click
310 * @param obj The given surface object uid
311 * @param position Mouse click position in pixels
312 * @return true if picked the surface otherwise returns false
314 boolean getLabel(Integer obj, Integer[] position) {
316 Double[] corners = (Double[])GraphicController.getController().getProperty(obj, GraphicObjectProperties.__GO_CORNERS__);
317 Double radAngle = (Double)GraphicController.getController().getProperty(obj, GraphicObjectProperties.__GO_FONT_ANGLE__);
318 int rotate = ((int)((radAngle * 2) / Math.PI)) % 2;
321 Double[] temp = new Double[corners.length];
322 for (Integer i = 0; i < corners.length - 3; i++) {
323 temp[i + 3] = corners[i];
325 temp[0] = corners[corners.length - 3];
326 temp[1] = corners[corners.length - 2];
327 temp[2] = corners[corners.length - 1];
330 double[] point = new double[] { 1.0 * position[0], 1.0 * position[1], 1.0};
331 double[] coord = CallRenderer.get2dViewFromPixelCoordinates(axesUID, point);
332 boolean[] logScale = { (Boolean)GraphicController.getController().getProperty(axesUID, GraphicObjectProperties.__GO_X_AXIS_LOG_FLAG__),
333 (Boolean)GraphicController.getController().getProperty(axesUID, GraphicObjectProperties.__GO_Y_AXIS_LOG_FLAG__)
335 coord[0] = CommonHandler.InverseLogScale(coord[0], logScale[0]);
336 coord[1] = CommonHandler.InverseLogScale(coord[1], logScale[1]);
338 if ((coord[0] >= corners[0] && coord[0] <= corners[6]) || (coord[0] <= corners[0] && coord[0] >= corners[6])) {
339 if ((coord[1] >= corners[1] && coord[1] <= corners[4]) || (coord[1] <= corners[1] && coord[1] >= corners[4])) {
347 * Arc picker, given a arc object it checks if the click
350 * @param obj The given arc object uid
351 * @param position Mouse click position in pixels
352 * @return true if picked the arc otherwise returns false
354 boolean getArc(Integer obj, Integer[] position) {
356 double[] upperLeft = (double[])ObjectData.getArcUpperLeftPoint(obj);
357 double[] data = (double[])ObjectData.getArcData(obj);
358 double[] pos = { position[0] * 1.0, position[1] * 1.0, 0.0 };
359 double[] c2d = CallRenderer.get2dViewFromPixelCoordinates(axesUID, pos);
362 double[] c2d2 = CallRenderer.get2dViewFromPixelCoordinates(axesUID, pos);
363 Boolean fill_mode = (Boolean)GraphicController.getController().getProperty(obj, GraphicObjectProperties.__GO_FILL_MODE__);
365 //Calculates the selection delta based on ellipse & axes size
366 double dt = Math.sqrt(Math.pow(c2d[0] - c2d2[0], 2.0) + Math.pow(c2d[1] - c2d2[1], 2.0)) / Math.sqrt((data[0] * data[0] / 4.) / 2. + (data[1] * data[1] / 4.) / 2.);
368 double[] c3d1 = AxesDrawer.compute3dViewCoordinates(axes, c2d);
370 double[] c3d2 = AxesDrawer.compute3dViewCoordinates(axes, c2d);
372 //Calculates the intersection of the click ray with the ellipse plane
373 Vector3d v0 = new Vector3d(c3d1);
374 Vector3d v1 = new Vector3d(c3d2);
375 Vector3d dir = v1.minus(v0);
377 if (dir.getZ() == 0) {
381 double u = (upperLeft[2] - v0.getZ()) / dir.getZ();
382 Vector3d point = v0.plus(dir.times(u));
384 double xr = data[1] / 2.;
385 double yr = data[0] / 2.;
387 Vector3d center = new Vector3d(upperLeft[0] + xr, upperLeft[1] - yr, upperLeft[2]);
389 //checks if the point lies within the ellipse
390 double x = point.getX() - center.getX();
391 double y = point.getY() - center.getY();
392 double v = (x * x) / (xr * xr) + (y * y) / (yr * yr);
398 double angle0 = getAngle360(data[2]);
399 double angle1 = getAngle360(data[3]) + angle0;
402 * Checks if the point is closer to the drawn arc
403 * and inside de given angles. If fill_mode = false
404 * it it accept 1-dt < value < 1+dt, if fill_mode = true
405 * it accept value < 1+dt;
408 v0 = new Vector3d(1.0, 0.0, 0.0);
409 v1 = point.minus(center);
410 double angle = Math.acos(v0.scalar(v1) / (v0.getNorm() * v1.getNorm()));
411 angle += v1.getY() < 0.0 ? Math.PI : 0.0;
413 if (!(angle0 == angle1) && !(angle >= angle0 && angle <= angle1)) {
419 } else if (v > 1.0 - dt) {
426 double getAngle360(double a) {
427 while (a > 2 * Math.PI) {
434 * Champ picker, given a champ object it checks if the click
437 * @param obj The given champ object uid
438 * @param position Mouse click position in pixels
439 * @return true if picked the champ otherwise returns false
441 boolean getChamp(Integer obj, Integer[] position) {
443 double[] datax = (double[])ObjectData.getChampX(obj);
444 double[] datay = (double[])ObjectData.getChampY(obj);
445 double[] data = (double[])ObjectData.getArrows(obj);
448 for (int i = 0; i < data.length; i++) {
449 scale = data[i] > scale ? data[i] : scale;
452 double[][] arrows = getAsStdMatrix(data, scale);
453 if (arrows == null) {
456 double[] pos = {1.0 * position[0], 1.0 * position[1], 1.0};
458 double[] c2d = CallRenderer.get2dViewFromPixelCoordinates(axesUID, pos);
461 double[] c2d2 = CallRenderer.get2dViewFromPixelCoordinates(axesUID, pos);
463 double dx = Math.abs(c2d[0] - c2d2[0]);
464 double dy = Math.abs(c2d[1] - c2d2[1]);
465 int xSize = datax.length;
466 int ySize = datay.length;
468 for (int i = 0; i < xSize; i++) {
469 for (int j = 0; j < ySize; j++) {
471 double[] ch2d = AxesDrawer.compute2dViewCoordinates(axes, new double[] { datax[i], datay[j], 0.0});
472 double[] temp = { datax[i] + arrows[i * xSize + j][0], datay[j] + arrows[i * xSize + j][1], arrows[i * xSize + j][2]};
473 double[] ch2d2 = AxesDrawer.compute2dViewCoordinates(axes, temp);
474 if (isInRange(ch2d[0], ch2d2[0], ch2d[1], ch2d2[1], c2d[0], c2d[1], dx, dy)) {
477 if ((Math.abs(c2d[0] - ch2d[0]) <= dx) && (Math.abs(c2d[1] - ch2d[1]) <= dy)) {
480 if ((Math.abs(c2d[0] - ch2d2[0]) <= dx) && (Math.abs(c2d[1] - ch2d2[1]) <= dy)) {
489 * Fec picker, given a fec object it checks if the click
492 * @param obj The given fec object uid
493 * @param position Mouse click position in pixels
494 * @return true if picked the fec otherwise returns false
496 boolean getFec(Integer obj, Integer[] position) {
497 int numVerticesByElem = ObjectData.getFecNumVerticesByElement(obj);
498 double[] elements = (double[])ObjectData.getFecElements(obj);
499 double[] data = (double[])ObjectData.getFecData(obj);
501 double[] pos = { position[0] * 1.0, position[1] * 1.0, 0.0 };
502 double[] c2d = CallRenderer.get2dViewFromPixelCoordinates(axesUID, pos);
503 double[] c3d1 = AxesDrawer.compute3dViewCoordinates(axes, c2d);
506 double[] c3d2 = AxesDrawer.compute3dViewCoordinates(axes, c2d);
507 Vector3d l0 = new Vector3d(c3d1);
508 Vector3d l1 = new Vector3d(c3d2);
509 Vector3d dir = l1.minus(l0);
510 int idx1, idx2, idx3;
513 int tSize = elements.length / (numVerticesByElem + 2);
514 for (int i = 0; i < tSize; i++) {
515 idx1 = (int)elements[tSize + i];
516 for (int j = 2; j < numVerticesByElem; ++j) {
517 idx2 = (int)elements[j * tSize + i];
518 idx3 = (int)elements[(j + 1) * tSize + i];
520 p1 = new Vector3d(data[(idx1 - 1) * 3], data[(idx1 - 1) * 3 + 1], data[(idx1 - 1) * 3 + 2]);
521 p2 = new Vector3d(data[(idx2 - 1) * 3], data[(idx2 - 1) * 3 + 1], data[(idx2 - 1) * 3 + 2]);
522 p3 = new Vector3d(data[(idx3 - 1) * 3], data[(idx3 - 1) * 3 + 1], data[(idx3 - 1) * 3 + 2]);
524 if (testTri(p1, p2, p3, l0, dir)) {
532 * Möller–Trumbore intersection algorithm
533 * Test if a line intersect a triangle
535 * @param p1 The vertex 1 of the triangle
536 * @param p2 The vertex 2 of the triangle
537 * @param p3 The vertex 3 of the triangle
538 * @param l0 origin point
539 * @param direction The direction vector
540 * @return true if it intersect the triangle, false otherwise
542 private boolean testTri(Vector3d p1, Vector3d p2, Vector3d p3, Vector3d l0, Vector3d direction) {
544 Vector3d e1 = p2.minus(p1);
545 Vector3d e2 = p3.minus(p1);
547 Vector3d h = Vector3d.product(direction, e2);
548 double det = e1.scalar(h);
550 if (det > -0.00001 && det < 0.00001) {
554 double inv = 1.0 / det;
555 Vector3d s = l0.minus(p1);
557 double u = s.scalar(h) * inv;
558 if (u < 0.0 || u > 1.0) {
562 Vector3d q = Vector3d.product(s, e1);
563 double v = direction.scalar(q) * inv;
564 if (v < 0.0 || (u + v) > 1.0) {
572 * Rectangle picker, given a rectangle object it checks if the click
575 * @param obj The given rectangle object uid
576 * @param position Mouse click position in pixels
577 * @return true if picked the rectangle otherwise returns false
579 boolean getRectangle(Integer obj, Integer[] position) {
581 Double[] upperLeft = (Double[])GraphicController.getController().getProperty(obj, GraphicObjectProperties.__GO_UPPER_LEFT_POINT__);
582 Double height = (Double)GraphicController.getController().getProperty(obj, GraphicObjectProperties.__GO_HEIGHT__);
583 Double width = (Double)GraphicController.getController().getProperty(obj, GraphicObjectProperties.__GO_WIDTH__);
584 double[] pos = { position[0] * 1.0, position[1] * 1.0, 0.0 };
585 double[] c2d = CallRenderer.get2dViewFromPixelCoordinates(axesUID, pos);
587 double[] c3d1 = AxesDrawer.compute3dViewCoordinates(axes, c2d);
589 double[] c3d2 = AxesDrawer.compute3dViewCoordinates(axes, c2d);
591 Vector3d v0 = new Vector3d(c3d1);
592 Vector3d v1 = new Vector3d(c3d2);
593 Vector3d c = v1.minus(v0);
599 double u = (upperLeft[2] - v0.getZ()) / c.getZ();
600 Vector3d point = v0.plus(c.times(u));
602 if (point.getX() >= upperLeft[0] && point.getX() <= (upperLeft[0] + width)
603 && point.getY() <= upperLeft[1] && point.getY() >= (upperLeft[1] - height)) {
610 * Segs picker, given a segs object it checks if the click
613 * @param obj The given segs object uid
614 * @param position Mouse click position in pixels
615 * @return true if picked the segs otherwise returns false
617 boolean getSegs(Integer obj, Integer[] position) {
619 double[][] base = getAsStdMatrix((double[])ObjectData.getSegsData(obj), 1.);
620 double[][] arrows = getAsStdMatrix((double[])ObjectData.getArrows(obj), 1.);
622 double[] pos = {1.0 * position[0], 1.0 * position[1], 1.0};
623 double[] c2d = CallRenderer.get2dViewFromPixelCoordinates(axesUID, pos);
626 double[] c2d2 = CallRenderer.get2dViewFromPixelCoordinates(axesUID, pos);
628 double dx = Math.abs(c2d[0] - c2d2[0]);
629 double dy = Math.abs(c2d[1] - c2d2[1]);
630 //System.out.println("Click: " + c2d[0] + "," + c2d[1]);
631 for (int i = 0; i < base.length; i++) {
632 double[] ch2d = AxesDrawer.compute2dViewCoordinates(axes, base[i]);
633 double[] ch2d2 = AxesDrawer.compute2dViewCoordinates(axes, arrows[i]);
634 //System.out.println("P1: " + ch2d[0] + "," + ch2d[1]);
635 //System.out.println("P2: " + ch2d2[0] + "," + ch2d2[1]);
636 if (isInRange(ch2d[0], ch2d2[0], ch2d[1], ch2d2[1], c2d[0], c2d[1], dx, dy)) {
644 * Datatip picker, given a datatip object it checks if the click
647 * @param obj The given datatip object uid
648 * @param position Mouse click position in pixels
649 * @return true if picked the datatip otherwise returns false
651 boolean getDatatip(Integer obj, Integer[] position) {
653 boolean[] logFlags = { axes.getXAxisLogFlag(), axes.getYAxisLogFlag(), axes.getZAxisLogFlag()};
654 double[] pix_pos = {1.0 * position[0], 1.0 * position[1], 1.0};
655 double[] c2d = CallRenderer.get2dViewFromPixelCoordinates(axesUID, pix_pos);
658 double[] c2d2 = CallRenderer.get2dViewFromPixelCoordinates(axesUID, pix_pos);
659 double dx = Math.abs(c2d[0] - c2d2[0]);
660 double dy = Math.abs(c2d[1] - c2d2[1]);
662 Double[] tip_pos = (Double[])GraphicController.getController().getProperty(obj, GraphicObjectProperties.__GO_DATATIP_DATA__);
663 double point[] = new double[3];
664 point[0] = CommonHandler.logScale(tip_pos[0], logFlags[0]);
665 point[1] = CommonHandler.logScale(tip_pos[1], logFlags[1]);
666 point[2] = CommonHandler.logScale(tip_pos[2], logFlags[2]);
668 Double[] rotAngles = (Double[])GraphicController.getController().getProperty(axesUID, GraphicObjectProperties.__GO_ROTATION_ANGLES__);
669 boolean default2dView = (rotAngles[0] == 0.0 && rotAngles[1] == 270.0);
671 if (!default2dView) {
672 point = AxesDrawer.compute2dViewCoordinates(axes, point);
675 Integer size = CommonHandler.getMarkSize(obj);
676 Integer unit = CommonHandler.getMarkSizeUnit(obj);
677 int finalSize = (unit == 1) ? (8 + 2 * size) : size;
680 if ((Math.abs(point[0] - c2d[0]) <= dx * finalSize) && (Math.abs(point[1] - c2d[1]) <= dy * finalSize)) {
684 //TODO: Add selection when the click is inside datatip textbox
689 boolean isInsideAxes(Integer figureUID, Integer[] position) {
690 Double[] rotAngles = (Double[])GraphicController.getController().getProperty(axesUID, GraphicObjectProperties.__GO_ROTATION_ANGLES__);
691 boolean default2dView = (rotAngles[0] == 0.0 && rotAngles[1] == 270.0);
692 // if (default2dView) {
693 Double[] dataBounds = (Double[])GraphicController.getController().getProperty(axesUID, GraphicObjectProperties.__GO_DATA_BOUNDS__);
694 double[] c2d = AxesDrawer.compute2dViewFromPixelCoordinates(axes, new double[] { 1.0 * position[0], 1.0 * position[1], 0.0 });
695 if (c2d[0] >= dataBounds[0] && c2d[0] <= dataBounds[1] && c2d[1] >= dataBounds[2] && c2d[1] <= dataBounds[3]) {
699 //TODO: Add check when it is in 3d view
705 void getObjects(Integer root, List<Integer> putObjs) {
707 Integer count = (Integer)GraphicController.getController().getProperty(root, GraphicObjectProperties.__GO_CHILDREN_COUNT__);
709 Integer[] children = (Integer[])GraphicController.getController().getProperty(root, GraphicObjectProperties.__GO_CHILDREN__);
710 for (int i = 0; i < count; i++) {
711 putObjs.add(children[i]);
712 getObjects(children[i], putObjs);
718 * Given an root object return an array with all children objects
720 * @param root The root object uid
721 * @return Array with all objects
723 Integer[] getAllObjAsArray(Integer root) {
725 List<Integer> objs = new LinkedList<Integer>();
726 getObjects(root, objs);
727 return objs.toArray(new Integer[objs.size()]);
730 private boolean isInRange(Double x0, Double x1, Double y0, Double y1, Double x, Double y, Double xRange, Double yRange) {
731 /* Fast bound check*/
732 double m = (x1 + x0) / 2;
735 double ca = (y1 - y0) / (x1 - x0);
737 double yy = y0 + ca * (x - x0);
739 double pix = xRange / delta;
740 double m_y = (y1 + y0) / 2;
741 double dy = m_y - y0;
743 boolean ca_inf = (Math.abs(x1 - x0) < Math.abs(pix * 2));
744 boolean in_bounds = (Math.abs(m - x) <= Math.abs(pix * 2)) && (Math.abs(m_y - y) <= Math.abs(dy));
747 * test if (x, y) belongs or is closer to the line
748 * if the angular coeficent -> inf(ca_inf), the interpolation fails
749 * then we use "in_bunds" test.
751 return (Math.abs(m - x) <= Math.abs(dx)) && (y >= (yy - yRange)) && (y <= (yy + yRange)) || (ca_inf && in_bounds);
754 private double[][] getAsStdMatrix(double[] data, double scale) {
756 double[][] ret = null;
757 if (data.length % 3 != 0) {
760 ret = new double[data.length / 3][3];
761 for (int i = 0; i < data.length / 3; i++) {
762 for (int j = 0; j < 3; j++) {
763 ret[i][j] = data[i * 3 + j] / scale;