001/* [{
002Copyright 2007, 2008 Nicolas Carranza <nicarran at gmail.com>
003
004This file is part of jpen.
005
006jpen is free software: you can redistribute it and/or modify
007it under the terms of the GNU Lesser General Public License as published by
008the Free Software Foundation, either version 3 of the License,
009or (at your option) any later version.
010
011jpen is distributed in the hope that it will be useful,
012but WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014GNU Lesser General Public License for more details.
015
016You should have received a copy of the GNU Lesser General Public License
017along with jpen.  If not, see <http://www.gnu.org/licenses/>.
018}] */
019package jpen;
020
021import java.awt.Component;
022import java.awt.Dimension;
023import java.awt.geom.Point2D;
024import java.util.Arrays;
025import java.util.Collections;
026import java.util.EnumSet;
027import java.util.List;
028import java.util.logging.Level;
029import java.util.logging.Logger;
030import java.util.Set;
031import static java.lang.Math.*;
032
033public class PLevel
034                        extends TypedValuedClass<PLevel.Type, Float>
035        implements java.io.Serializable {
036        private static final Logger L=Logger.getLogger(PLevel.class.getName());
037        //static{L.setLevel(Level.FINE);}
038        public static final long serialVersionUID=1l;
039
040        public enum Type{
041                /**
042                X axis value in pixels. The X axis points to the right of the screen. It's a left handed coordinate system: the Z axis points upside.
043                */
044                X,
045                /**
046                Y axis value in pixels. The Y axis points to the bottom of the screen.
047                */
048                Y,
049                /**
050                Range: 0 to 1.
051                */
052                PRESSURE,
053                /**
054                Angle between the Z axis and the projection of the pen against the X-Z plane. Range: -pi/2 to pi/2 radians.
055                */
056                TILT_X,
057                /**
058                Angle between the Z axis and the projection of the pen against the Y-Z plane. Range: -pi/2 to pi/2 radians.
059                */
060                TILT_Y,
061                /**
062                Barrel button or wheel. Range: 0 to 1 towards the pen tip.<p>
063                <b>Warning:</b> Testing needed. The development team does not have an airbrush to test on all platforms. Please help us giving feedback (<a href="http://sourceforge.net/projects/jpen/forums/forum/753961">start a topic on the help forum</a>):
064                        <ul>
065                                <li>Which operating system are you using?</li>
066                                <li>Does the value grow (0 to 1) when the wheel is moved towards the pen tip?</li>
067                                <li>Are you using an airbrush or a pen marker?</li>
068                        </ul>
069                 */
070                SIDE_PRESSURE,
071                /**
072                Pen rotation. Range: 0 to 2*pi clockwise.
073                <b>Warning:</b> Testing needed. The development team does not have a pen marker or 4D mouse to test on all platforms. Please help us giving feedback (<a href="http://sourceforge.net/projects/jpen/forums/forum/753961">start a topic on the help forum</a>):
074                        <ul>
075                                <li>Which operating system are you using?</li>
076                                <li>Does the value grow from 0 to 2*pi when the device is moved clockwise?</li>
077                                <li>Are you using a pen marker or 4D mouse?</li>
078                        </ul>
079                 */
080                ROTATION,
081                CUSTOM;
082
083                public static final List<Type> ALL_VALUES=Collections.unmodifiableList(Arrays.asList(values()));
084                public static final List<Type> VALUES=TypedClass.createStandardTypes(ALL_VALUES);
085                public static final Set<Type> MOVEMENT_TYPES=Collections.unmodifiableSet(EnumSet.of(X, Y));
086                public static final Set<Type> TILT_TYPES=Collections.unmodifiableSet(EnumSet.of(TILT_X, TILT_Y));
087
088                /**
089                Evaluates the azimuthX and altitude given the tilt values of the pen.
090
091                @see #evalAzimuthXAndAltitude(double[], double tiltX, double tiltY)
092                */
093                public static void evalAzimuthXAndAltitude(double[] azimuthXAndAltitude, PenState pen){
094                        evalAzimuthXAndAltitude(azimuthXAndAltitude, pen.getLevelValue(TILT_X), pen.getLevelValue(TILT_Y));
095                }
096
097                /**
098                Evaluates the azimuthX and the altitude given the tilt ({@link #TILT_X}, {@link #TILT_Y}) values. Where:<p>
099        {@code azimuthX} is the angle between the X axis and the projection of the pen against the X-Y plane. Clockwise direction. Range: -pi/2 and 3*pi/2 <p>
100                And {@code altitude} is the angle between the pen and the projection of the pen against the X-Y plane. Range: 0 to pi/2.
101                */
102                public static void evalAzimuthXAndAltitude(double[] azimuthXAndAltitude, double tiltX, double tiltY){
103                        if(tiltX<0)
104                                azimuthXAndAltitude[0]=PI;
105                        else if(tiltX==0 && tiltY==0){
106                                azimuthXAndAltitude[0]=0;
107                                azimuthXAndAltitude[1]=PI_over_2;
108                                return;
109                        } else
110                                azimuthXAndAltitude[0]=0;
111                        double tanTiltY=tan(tiltY);
112                        azimuthXAndAltitude[0]+=atan(tanTiltY/tan(tiltX));
113                        azimuthXAndAltitude[1]=azimuthXAndAltitude[0]==0?
114                                        PI_over_2-tiltX:
115                                        Math.abs(atan(sin(azimuthXAndAltitude[0])/tanTiltY));
116                }
117
118                private static final double PI_over_2=PI/2;
119        }
120
121        public PLevel(PLevel level){
122                this(level.typeNumber, level.value);
123        }
124
125        public PLevel(Type type, float value){
126                this(type.ordinal(), value);
127        }
128
129        public PLevel(int typeNumber, float value) {
130                super(typeNumber, value);
131        }
132
133        @Override
134        final List<Type> getAllTypes() {
135                return Type.ALL_VALUES;
136        }
137
138        public boolean isMovement() {
139                return Type.MOVEMENT_TYPES.contains(getType());
140        }
141}