/*
* $Id$
* This file is a part of the Arakhne Foundation Classes, http://www.arakhne.org/afc
*
* Copyright (c) 2000-2012 Stephane GALLAND.
* Copyright (c) 2005-10, Multiagent Team, Laboratoire Systemes et Transports,
* Universite de Technologie de Belfort-Montbeliard.
* Copyright (c) 2013-2016 The original authors, and other authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.arakhne.afc.ui;
import org.arakhne.afc.math.continous.object2d.Circle2f;
import org.arakhne.afc.math.continous.object2d.Ellipse2f;
import org.arakhne.afc.math.continous.object2d.Path2f;
import org.arakhne.afc.math.continous.object2d.PathElement2f;
import org.arakhne.afc.math.continous.object2d.PathIterator2f;
import org.arakhne.afc.math.continous.object2d.Point2f;
import org.arakhne.afc.math.continous.object2d.Rectangle2f;
import org.arakhne.afc.math.continous.object2d.RoundRectangle2f;
import org.arakhne.afc.math.continous.object2d.Segment2f;
import org.arakhne.afc.math.continous.object2d.Shape2f;
import org.arakhne.afc.math.generic.PathWindingRule;
/** Utilities for ZoomableContext.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
* @deprecated see JavaFX API
*/
@Deprecated
public class ZoomableContextUtil {
/** Replies the scaling factor that permits to pass
* from the given size expressed in the logical space to
* the given size expressed in the pixel space.
*
* @param sizeInLogicalSpace is the size in the logical space. Must not be strictly positive.
* @param sizeInPixelSpace is the size in the screen/pixel space. Must not be strictly positive.
* @return the scaling factor to pass from the logical size to the pixel size.
*/
public static float determineFactor(float sizeInLogicalSpace, float sizeInPixelSpace) {
assert(sizeInLogicalSpace>0f) : "sizeInLogicalSpace is not strictly positive"; //$NON-NLS-1$
assert(sizeInPixelSpace>0f) : "sizeInPixelSpace is not strictly positive"; //$NON-NLS-1$
return sizeInPixelSpace / sizeInLogicalSpace;
}
/** Translates the specified path
* into the screen space.
*
* @param p is the path in the logical.
* @param centeringTransform is the transform to apply to the points to change from/to the coordinate
* system from the "global" logical coordinate system to/from the "centered" logical coordinate
* system.
* @param zoom is the current zooming factor of the view.
* @return the path is screen path.
*/
public static PathIterator2f logical2pixel(PathIterator2f p,
CenteringTransform centeringTransform,
float zoom) {
return new L2PPathIterator(p, centeringTransform, zoom);
}
/** Translates the specified path
* into the logical space.
*
* @param p is the path in the screen space.
* @param centeringTransform is the transform to apply to the points to change from/to the coordinate
* system from the "global" logical coordinate system to/from the "centered" logical coordinate
* system.
* @param zoom is the current zooming factor of the view.
* @return the path in logical space.
*/
public static PathIterator2f pixel2logical(PathIterator2f p,
CenteringTransform centeringTransform,
float zoom) {
return new P2LPathIterator(p, centeringTransform, zoom);
}
/** Translates the specified segment
* into the screen space.
*
* @param s is the segment in the logical space when input and the
* same segment in screen space when output.
* @param centeringTransform is the transform to apply to the points to change from/to the coordinate
* system from the "global" logical coordinate system to/from the "centered" logical coordinate
* system.
* @param zoom is the current zooming factor of the view.
*/
public static void logical2pixel(Segment2f s,
CenteringTransform centeringTransform,
float zoom) {
assert(s!=null);
assert(centeringTransform!=null);
s.set(
logical2pixel_x(s.getX1(), centeringTransform, zoom),
logical2pixel_y(s.getY1(), centeringTransform, zoom),
logical2pixel_x(s.getX2(), centeringTransform, zoom),
logical2pixel_y(s.getY2(), centeringTransform, zoom));
}
/** Translates the specified segment
* into the logical space.
*
* @param s is the segment in the screen space when input and the
* same segment in logical space when output.
* @param centeringTransform is the transform to apply to the points to change from/to the coordinate
* system from the "global" logical coordinate system to/from the "centered" logical coordinate
* system.
* @param zoom is the current zooming factor of the view.
*/
public static void pixel2logical(Segment2f s,
CenteringTransform centeringTransform,
float zoom) {
assert(s!=null);
assert(centeringTransform!=null);
s.set(
pixel2logical_x(s.getX1(), centeringTransform, zoom),
pixel2logical_y(s.getX1(), centeringTransform, zoom),
pixel2logical_x(s.getX2(), centeringTransform, zoom),
pixel2logical_y(s.getX2(), centeringTransform, zoom));
}
/** Translates the specified rectangle
* into the screen space.
*
* @param r is the rectangle in the logical space when input and the
* same rectangle in screen space when output.
* @param centeringTransform is the transform to apply to the points to change from/to the coordinate
* system from the "global" logical coordinate system to/from the "centered" logical coordinate
* system.
* @param zoom is the current zooming factor of the view.
*/
public static void logical2pixel(RoundRectangle2f r,
CenteringTransform centeringTransform,
float zoom) {
assert(r!=null);
assert(centeringTransform!=null);
float x = centeringTransform.isXAxisFlipped() ? r.getMaxX() : r.getMinX();
float y = centeringTransform.isYAxisFlipped() ? r.getMaxY() : r.getMinY();
r.set(
logical2pixel_x(x, centeringTransform, zoom),
logical2pixel_y(y, centeringTransform, zoom),
logical2pixel_size(r.getWidth(), zoom),
logical2pixel_size(r.getHeight(), zoom),
logical2pixel_size(r.getArcWidth(), zoom),
logical2pixel_size(r.getArcHeight(), zoom));
}
/** Translates the specified rectangle
* into the logical space.
*
* @param r is the rectangle in the screen space when input and the
* same rectangle in logical space when output.
* @param centeringTransform is the transform to apply to the points to change from/to the coordinate
* system from the "global" logical coordinate system to/from the "centered" logical coordinate
* system.
* @param zoom is the current zooming factor of the view.
*/
public static void pixel2logical(RoundRectangle2f r,
CenteringTransform centeringTransform,
float zoom) {
assert(r!=null);
assert(centeringTransform!=null);
float x = centeringTransform.isXAxisFlipped() ? r.getMaxX() : r.getMinX();
float y = centeringTransform.isYAxisFlipped() ? r.getMaxY() : r.getMinY();
r.set(
pixel2logical_x(x, centeringTransform, zoom),
pixel2logical_y(y, centeringTransform, zoom),
pixel2logical_size(r.getWidth(), zoom),
pixel2logical_size(r.getHeight(), zoom),
pixel2logical_size(r.getArcWidth(), zoom),
pixel2logical_size(r.getArcHeight(), zoom));
}
/** Translates the specified point
* into the screen space.
*
* @param p is the point in the logical space when input and the
* same point in screen space when output.
* @param centeringTransform is the transform to apply to the points to change from/to the coordinate
* system from the "global" logical coordinate system to/from the "centered" logical coordinate
* system.
* @param zoom is the current zooming factor of the view.
*/
public static void logical2pixel(Point2f p,
CenteringTransform centeringTransform,
float zoom) {
assert(p!=null);
assert(centeringTransform!=null);
p.set(
logical2pixel_x(p.getX(), centeringTransform, zoom),
logical2pixel_y(p.getY(), centeringTransform, zoom));
}
/** Translates the specified point
* into the logical space.
*
* @param p is the point in the screen space when input and the
* same point in logical space when output.
* @param centeringTransform is the transform to apply to the points to change from/to the coordinate
* system from the "global" logical coordinate system to/from the "centered" logical coordinate
* system.
* @param zoom is the current zooming factor of the view.
*/
public static void pixel2logical(Point2f p,
CenteringTransform centeringTransform,
float zoom) {
assert(p!=null);
assert(centeringTransform!=null);
p.set(
pixel2logical_x(p.getX(), centeringTransform, zoom),
pixel2logical_y(p.getY(), centeringTransform, zoom));
}
/** Translates the specified ellipse
* into the screen space.
*
* @param e is the ellipse in the logical space when input and the
* same ellipse in screen space when output.
* @param centeringTransform is the transform to apply to the points to change from/to the coordinate
* system from the "global" logical coordinate system to/from the "centered" logical coordinate
* system.
* @param zoom is the current zooming factor of the view.
*/
public static void logical2pixel(Ellipse2f e,
CenteringTransform centeringTransform,
float zoom) {
assert(e!=null);
assert(centeringTransform!=null);
float x = centeringTransform.isXAxisFlipped() ? e.getMaxX() : e.getMinX();
float y = centeringTransform.isYAxisFlipped() ? e.getMaxY() : e.getMinY();
e.set(
logical2pixel_x(x, centeringTransform, zoom),
logical2pixel_y(y, centeringTransform, zoom),
logical2pixel_size(e.getWidth(), zoom),
logical2pixel_size(e.getHeight(), zoom));
}
/** Translates the specified ellipse
* into the logical space.
*
* @param e is the ellipse in the screen space when input and the
* same ellipse in logical space when output.
* @param centeringTransform is the transform to apply to the points to change from/to the coordinate
* system from the "global" logical coordinate system to/from the "centered" logical coordinate
* system.
* @param zoom is the current zooming factor of the view.
*/
public static void pixel2logical(Ellipse2f e,
CenteringTransform centeringTransform,
float zoom) {
assert(e!=null);
assert(centeringTransform!=null);
float x = centeringTransform.isXAxisFlipped() ? e.getMaxX() : e.getMinX();
float y = centeringTransform.isYAxisFlipped() ? e.getMaxY() : e.getMinY();
e.set(
pixel2logical_x(x, centeringTransform, zoom),
pixel2logical_y(y, centeringTransform, zoom),
pixel2logical_size(e.getWidth(), zoom),
pixel2logical_size(e.getHeight(), zoom));
}
/** Translates the specified circle
* into the screen space.
*
* @param r is the rectangle in the logical space when input and the
* same rectangle in screen space when output.
* @param centeringTransform is the transform to apply to the points to change from/to the coordinate
* system from the "global" logical coordinate system to/from the "centered" logical coordinate
* system.
* @param zoom is the current zooming factor of the view.
*/
public static void logical2pixel(Circle2f r,
CenteringTransform centeringTransform,
float zoom) {
assert(r!=null);
assert(centeringTransform!=null);
r.set(
logical2pixel_x(r.getX(), centeringTransform, zoom),
logical2pixel_y(r.getY(), centeringTransform, zoom),
logical2pixel_size(r.getRadius(), zoom));
}
/** Translates the specified circle
* into the logical space.
*
* @param r is the rectangle in the screen space when input and the
* same rectangle in logical space when output.
* @param centeringTransform is the transform to apply to the points to change from/to the coordinate
* system from the "global" logical coordinate system to/from the "centered" logical coordinate
* system.
* @param zoom is the current zooming factor of the view.
*/
public static void pixel2logical(Circle2f r,
CenteringTransform centeringTransform,
float zoom) {
assert(r!=null);
assert(centeringTransform!=null);
r.set(
pixel2logical_x(r.getX(), centeringTransform, zoom),
pixel2logical_y(r.getY(), centeringTransform, zoom),
pixel2logical_size(r.getRadius(), zoom));
}
/** Translates the specified rectangle
* into the screen space.
*
* @param r is the rectangle in the logical space when input and the
* same rectangle in screen space when output.
* @param centeringTransform is the transform to apply to the points to change from/to the coordinate
* system from the "global" logical coordinate system to/from the "centered" logical coordinate
* system.
* @param zoom is the current zooming factor of the view.
*/
public static void logical2pixel(Rectangle2f r,
CenteringTransform centeringTransform,
float zoom) {
assert(r!=null);
assert(centeringTransform!=null);
float x = centeringTransform.isXAxisFlipped() ? r.getMaxX() : r.getMinX();
float y = centeringTransform.isYAxisFlipped() ? r.getMaxY() : r.getMinY();
r.set(
logical2pixel_x(x, centeringTransform, zoom),
logical2pixel_y(y, centeringTransform, zoom),
logical2pixel_size(r.getWidth(), zoom),
logical2pixel_size(r.getHeight(), zoom));
}
/** Translates the specified rectangle
* into the logical space.
*
* @param r is the rectangle in the screen space when input and the
* same rectangle in logical space when output.
* @param centeringTransform is the transform to apply to the points to change from/to the coordinate
* system from the "global" logical coordinate system to/from the "centered" logical coordinate
* system.
* @param zoom is the current zooming factor of the view.
*/
public static void pixel2logical(Rectangle2f r,
CenteringTransform centeringTransform,
float zoom) {
assert(r!=null);
assert(centeringTransform!=null);
float x = centeringTransform.isXAxisFlipped() ? r.getMaxX() : r.getMinX();
float y = centeringTransform.isYAxisFlipped() ? r.getMaxY() : r.getMinY();
r.set(
pixel2logical_x(x, centeringTransform, zoom),
pixel2logical_y(y, centeringTransform, zoom),
pixel2logical_size(r.getWidth(), zoom),
pixel2logical_size(r.getHeight(), zoom));
}
/** Translates the specified shape
* into the screen space.
* <p>
* <strong>CAUTION:</strong> You must prefer to invoke
* one of the other functions of this ZoomableContext
* to run a faster translation algorithm than the
* algorithm implemented in this function.
*
* @param s is the shape in the logical space to translate.
* @param centeringTransform is the transform to apply to the points to change from/to the coordinate
* system from the "global" logical coordinate system to/from the "centered" logical coordinate
* system.
* @param zoom is the current zooming factor of the view.
* @return the result of the translation.
*/
public static Shape2f logical2pixel(Shape2f s,
CenteringTransform centeringTransform,
float zoom) {
assert(s!=null);
assert(centeringTransform!=null);
if (s instanceof Rectangle2f) {
Rectangle2f r = ((Rectangle2f)s).clone();
logical2pixel(r, centeringTransform, zoom);
return r;
}
if (s instanceof Circle2f) {
Circle2f r = ((Circle2f)s).clone();
logical2pixel(r, centeringTransform, zoom);
return r;
}
if (s instanceof Ellipse2f) {
Ellipse2f r = ((Ellipse2f)s).clone();
logical2pixel(r, centeringTransform, zoom);
return r;
}
if (s instanceof RoundRectangle2f) {
RoundRectangle2f r = ((RoundRectangle2f)s).clone();
logical2pixel(r, centeringTransform, zoom);
return r;
}
if (s instanceof Segment2f) {
Segment2f r = ((Segment2f)s).clone();
logical2pixel(r, centeringTransform, zoom);
return r;
}
return new Path2f(logical2pixel(s.getPathIterator(), centeringTransform, zoom));
}
/** Translates the specified shape
* into the logical space.
* <p>
* <strong>CAUTION:</strong> You must prefer to invoke
* one of the other functions of this ZoomableContext
* to run a faster translation algorithm than the
* algorithm implemented in this function.
*
* @param s is the shape in the screen space to translate.
* @param centeringTransform is the transform to apply to the points to change from/to the coordinate
* system from the "global" logical coordinate system to/from the "centered" logical coordinate
* system.
* @param zoom is the current zooming factor of the view.
* @return the result of the translation.
*/
public static Shape2f pixel2logical(Shape2f s,
CenteringTransform centeringTransform,
float zoom) {
assert(s!=null);
assert(centeringTransform!=null);
if (s instanceof Rectangle2f) {
Rectangle2f r = ((Rectangle2f)s).clone();
pixel2logical(r, centeringTransform, zoom);
return r;
}
if (s instanceof Circle2f) {
Circle2f r = ((Circle2f)s).clone();
pixel2logical(r, centeringTransform, zoom);
return r;
}
if (s instanceof Ellipse2f) {
Ellipse2f r = ((Ellipse2f)s).clone();
pixel2logical(r, centeringTransform, zoom);
return r;
}
if (s instanceof RoundRectangle2f) {
RoundRectangle2f r = ((RoundRectangle2f)s).clone();
pixel2logical(r, centeringTransform, zoom);
return r;
}
if (s instanceof Segment2f) {
Segment2f r = ((Segment2f)s).clone();
pixel2logical(r, centeringTransform, zoom);
return r;
}
return new Path2f(logical2pixel(s.getPathIterator(), centeringTransform, zoom));
}
/** Translates the specified workspace location
* into the screen location.
*
* @param l is the coordinate along the workspace space X-axis.
* @param centeringTransform is the transform to apply to the points to change from/to the coordinate
* system from the "global" logical coordinate system to/from the "centered" logical coordinate
* system.
* @param zoom is the current zooming factor of the view.
* @return a location along the screen space X-axis.
*/
public static float logical2pixel_x(float l, CenteringTransform centeringTransform,
float zoom) {
return centeringTransform.toCenterX(l) * zoom;
}
/** Translates the specified workspace location
* into the screen location.
*
* @param l is the coordinate along the workspace space Y-axis.
* @param centeringTransform is the transform to apply to the points to change from/to the coordinate
* system from the "global" logical coordinate system to/from the "centered" logical coordinate
* system.
* @param zoom is the current zooming factor of the view.
* @return a location along the screen space Y-axis.
*/
public static float logical2pixel_y(float l,
CenteringTransform centeringTransform, float zoom) {
return centeringTransform.toCenterY(l) * zoom;
}
/** Translates the specified screen location
* into the logical location.
*
* @param p is the location along the screen space X-axis.
* @param centeringTransform is the transform to apply to the points to change from/to the coordinate
* system from the "global" logical coordinate system to/from the "centered" logical coordinate
* system.
* @param zoom is the current zooming factor of the view.
* @return a location along the logical space X-axis.
*/
public static float pixel2logical_x(float p,
CenteringTransform centeringTransform, float zoom) {
return centeringTransform.toGlobalX(p/zoom);
}
/** Translates the specified screen location
* into the logical location.
*
* @param p is the location along the screen space Y-axis.
* @param centeringTransform is the transform to apply to the points to change from/to the coordinate
* system from the "global" logical coordinate system to/from the "centered" logical coordinate
* system.
* @param zoom is the current zooming factor of the view.
* @return a location along the logical space Y-axis.
*/
public static float pixel2logical_y(float p, CenteringTransform centeringTransform, float zoom) {
return centeringTransform.toGlobalY(p/zoom);
}
/** Translates the specified workspace length
* into the screen length.
*
* @param l is the length in the workspace space.
* @param zoom is the current zooming factor of the view.
* @return a length into the screen space.
*/
public static float logical2pixel_size(float l, float zoom) {
float s = l * zoom;
if ((l!=0)&&(s==0)) s = 1f;
return s;
}
/** Translates the specified screen length
* into the logical length.
*
* @param l is the length in the screen space.
* @param zoom is the current zooming factor of the view.
* @return a length into the logical space.
*/
public static float pixel2logical_size(float l, float zoom) {
return l / zoom;
}
/** Pixel-to-logical translator for path iterator.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
*/
public static class P2LPathIterator implements PathIterator2f {
private final float[] coords = new float[6];
private final PathIterator2f it;
private final CenteringTransform ct;
private final float z;
/**
* @param it is the iterator to translate from pixel to logical coordinate system.
* @param ct is the transformation to apply to center the transformation on the view.
* @param z is the scaling factor for the translation.
*/
public P2LPathIterator(PathIterator2f it, CenteringTransform ct, float z) {
this.it = it;
this.ct = ct;
this.z = z;
}
@Override
public boolean hasNext() {
return this.it.hasNext();
}
@Override
public PathElement2f next() {
PathElement2f p = this.it.next();
p.toArray(this.coords);
for(int i=0; i<this.coords.length;) {
this.coords[i] = logical2pixel_x(this.coords[i], this.ct, this.z);
++i;
this.coords[i] = logical2pixel_y(this.coords[i], this.ct, this.z);
++i;
}
return PathElement2f.newInstance(
p.type,
logical2pixel_x(p.fromX, this.ct, this.z),
logical2pixel_y(p.fromY, this.ct, this.z),
this.coords);
}
@Override
public void remove() {
this.it.remove();
}
@Override
public PathWindingRule getWindingRule() {
return this.it.getWindingRule();
}
@Override
public boolean isPolyline() {
return this.it.isPolyline();
}
}
/** Logical-to-pixel translator for path iterator.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
*/
public static class L2PPathIterator implements PathIterator2f {
private final float[] coords = new float[6];
private final PathIterator2f it;
private final CenteringTransform ct;
private final float z;
/**
* @param it is the iterator to translate from logical to pixel coordinate system.
* @param ct is the transformation to apply to center the transformation on the view.
* @param z is the scaling factor for the translation.
*/
public L2PPathIterator(PathIterator2f it, CenteringTransform ct, float z) {
this.it = it;
this.ct = ct;
this.z = z;
}
@Override
public boolean hasNext() {
return this.it.hasNext();
}
@Override
public PathElement2f next() {
PathElement2f p = this.it.next();
p.toArray(this.coords);
for(int i=0; i<this.coords.length;) {
this.coords[i] = logical2pixel_x(this.coords[i], this.ct, this.z);
++i;
this.coords[i] = logical2pixel_y(this.coords[i], this.ct, this.z);
++i;
}
return PathElement2f.newInstance(
p.type,
logical2pixel_x(p.fromX, this.ct, this.z),
logical2pixel_y(p.fromY, this.ct, this.z),
this.coords);
}
@Override
public void remove() {
this.it.remove();
}
@Override
public PathWindingRule getWindingRule() {
return this.it.getWindingRule();
}
@Override
public boolean isPolyline() {
return this.it.isPolyline();
}
}
}