001/*
002Copyright 2006 Jerry Huxtable
003
004Licensed under the Apache License, Version 2.0 (the "License");
005you may not use this file except in compliance with the License.
006You may obtain a copy of the License at
007
008   http://www.apache.org/licenses/LICENSE-2.0
009
010Unless required by applicable law or agreed to in writing, software
011distributed under the License is distributed on an "AS IS" BASIS,
012WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013See the License for the specific language governing permissions and
014limitations under the License.
015*/
016
017package com.jhlabs.image;
018
019import java.awt.*;
020import java.awt.image.*;
021import com.jhlabs.math.*;
022
023/**
024 * A filter which distorts an image by rippling it in the X or Y directions.
025 * The amplitude and wavelength of rippling can be specified as well as whether 
026 * pixels going off the edges are wrapped or not.
027 */
028public class RippleFilter extends TransformFilter {
029        
030    /**
031     * Sine wave ripples.
032     */
033        public final static int SINE = 0;
034
035    /**
036     * Sawtooth wave ripples.
037     */
038        public final static int SAWTOOTH = 1;
039
040    /**
041     * Triangle wave ripples.
042     */
043        public final static int TRIANGLE = 2;
044
045    /**
046     * Noise ripples.
047     */
048        public final static int NOISE = 3;
049
050        private float xAmplitude, yAmplitude;
051        private float xWavelength, yWavelength;
052        private int waveType;
053
054        /**
055         * Construct a RippleFilter.
056         */
057        public RippleFilter() {
058                xAmplitude = 5.0f;
059                yAmplitude = 0.0f;
060                xWavelength = yWavelength = 16.0f;
061        }
062
063        /**
064         * Set the amplitude of ripple in the X direction.
065         * @param xAmplitude the amplitude (in pixels).
066     * @see #getXAmplitude
067         */
068        public void setXAmplitude(float xAmplitude) {
069                this.xAmplitude = xAmplitude;
070        }
071
072        /**
073         * Get the amplitude of ripple in the X direction.
074         * @return the amplitude (in pixels).
075     * @see #setXAmplitude
076         */
077        public float getXAmplitude() {
078                return xAmplitude;
079        }
080
081        /**
082         * Set the wavelength of ripple in the X direction.
083         * @param xWavelength the wavelength (in pixels).
084     * @see #getXWavelength
085         */
086        public void setXWavelength(float xWavelength) {
087                this.xWavelength = xWavelength;
088        }
089
090        /**
091         * Get the wavelength of ripple in the X direction.
092         * @return the wavelength (in pixels).
093     * @see #setXWavelength
094         */
095        public float getXWavelength() {
096                return xWavelength;
097        }
098
099        /**
100         * Set the amplitude of ripple in the Y direction.
101         * @param yAmplitude the amplitude (in pixels).
102     * @see #getYAmplitude
103         */
104        public void setYAmplitude(float yAmplitude) {
105                this.yAmplitude = yAmplitude;
106        }
107
108        /**
109         * Get the amplitude of ripple in the Y direction.
110         * @return the amplitude (in pixels).
111     * @see #setYAmplitude
112         */
113        public float getYAmplitude() {
114                return yAmplitude;
115        }
116
117        /**
118         * Set the wavelength of ripple in the Y direction.
119         * @param yWavelength the wavelength (in pixels).
120     * @see #getYWavelength
121         */
122        public void setYWavelength(float yWavelength) {
123                this.yWavelength = yWavelength;
124        }
125
126        /**
127         * Get the wavelength of ripple in the Y direction.
128         * @return the wavelength (in pixels).
129     * @see #setYWavelength
130         */
131        public float getYWavelength() {
132                return yWavelength;
133        }
134
135
136        /**
137         * Set the wave type.
138         * @param waveType the type.
139     * @see #getWaveType
140         */
141        public void setWaveType(int waveType) {
142                this.waveType = waveType;
143        }
144
145        /**
146         * Get the wave type.
147         * @return the type.
148     * @see #setWaveType
149         */
150        public int getWaveType() {
151                return waveType;
152        }
153
154        protected void transformSpace(Rectangle r) {
155                if (edgeAction == ZERO) {
156                        r.x -= (int)xAmplitude;
157                        r.width += (int)(2*xAmplitude);
158                        r.y -= (int)yAmplitude;
159                        r.height += (int)(2*yAmplitude);
160                }
161        }
162
163        protected void transformInverse(int x, int y, float[] out) {
164                float nx = (float)y / xWavelength;
165                float ny = (float)x / yWavelength;
166                float fx, fy;
167                switch (waveType) {
168                case SINE:
169                default:
170                        fx = (float)Math.sin(nx);
171                        fy = (float)Math.sin(ny);
172                        break;
173                case SAWTOOTH:
174                        fx = ImageMath.mod(nx, 1);
175                        fy = ImageMath.mod(ny, 1);
176                        break;
177                case TRIANGLE:
178                        fx = ImageMath.triangle(nx);
179                        fy = ImageMath.triangle(ny);
180                        break;
181                case NOISE:
182                        fx = Noise.noise1(nx);
183                        fy = Noise.noise1(ny);
184                        break;
185                }
186                out[0] = x + xAmplitude * fx;
187                out[1] = y + yAmplitude * fy;
188        }
189
190        public String toString() {
191                return "Distort/Ripple...";
192        }
193
194}