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 as if it were underwater. 025 */ 026public class SwimFilter extends TransformFilter { 027 028 private float scale = 32; 029 private float stretch = 1.0f; 030 private float angle = 0.0f; 031 private float amount = 1.0f; 032 private float turbulence = 1.0f; 033 private float time = 0.0f; 034 private float m00 = 1.0f; 035 private float m01 = 0.0f; 036 private float m10 = 0.0f; 037 private float m11 = 1.0f; 038 039 public SwimFilter() { 040 } 041 042 /** 043 * Set the amount of swim. 044 * @param amount the amount of swim 045 * @min-value 0 046 * @max-value 100+ 047 * @see #getAmount 048 */ 049 public void setAmount(float amount) { 050 this.amount = amount; 051 } 052 053 /** 054 * Get the amount of swim. 055 * @return the amount swim 056 * @see #setAmount 057 */ 058 public float getAmount() { 059 return amount; 060 } 061 062 /** 063 * Specifies the scale of the distortion. 064 * @param scale the scale of the distortion. 065 * @min-value 1 066 * @max-value 300+ 067 * @see #getScale 068 */ 069 public void setScale(float scale) { 070 this.scale = scale; 071 } 072 073 /** 074 * Returns the scale of the distortion. 075 * @return the scale of the distortion. 076 * @see #setScale 077 */ 078 public float getScale() { 079 return scale; 080 } 081 082 /** 083 * Specifies the stretch factor of the distortion. 084 * @param stretch the stretch factor of the distortion. 085 * @min-value 1 086 * @max-value 50+ 087 * @see #getStretch 088 */ 089 public void setStretch(float stretch) { 090 this.stretch = stretch; 091 } 092 093 /** 094 * Returns the stretch factor of the distortion. 095 * @return the stretch factor of the distortion. 096 * @see #setStretch 097 */ 098 public float getStretch() { 099 return stretch; 100 } 101 102 /** 103 * Specifies the angle of the effect. 104 * @param angle the angle of the effect. 105 * @angle 106 * @see #getAngle 107 */ 108 public void setAngle(float angle) { 109 this.angle = angle; 110 float cos = (float)Math.cos(angle); 111 float sin = (float)Math.sin(angle); 112 m00 = cos; 113 m01 = sin; 114 m10 = -sin; 115 m11 = cos; 116 } 117 118 /** 119 * Returns the angle of the effect. 120 * @return the angle of the effect. 121 * @see #setAngle 122 */ 123 public float getAngle() { 124 return angle; 125 } 126 127 /** 128 * Specifies the turbulence of the texture. 129 * @param turbulence the turbulence of the texture. 130 * @min-value 0 131 * @max-value 1 132 * @see #getTurbulence 133 */ 134 public void setTurbulence(float turbulence) { 135 this.turbulence = turbulence; 136 } 137 138 /** 139 * Returns the turbulence of the effect. 140 * @return the turbulence of the effect. 141 * @see #setTurbulence 142 */ 143 public float getTurbulence() { 144 return turbulence; 145 } 146 147 /** 148 * Specifies the time. Use this to animate the effect. 149 * @param time the time. 150 * @angle 151 * @see #getTime 152 */ 153 public void setTime(float time) { 154 this.time = time; 155 } 156 157 /** 158 * Returns the time. 159 * @return the time. 160 * @see #setTime 161 */ 162 public float getTime() { 163 return time; 164 } 165 166 protected void transformInverse(int x, int y, float[] out) { 167 float nx = m00*x + m01*y; 168 float ny = m10*x + m11*y; 169 nx /= scale; 170 ny /= scale * stretch; 171 172 if ( turbulence == 1.0f ) { 173 out[0] = x + amount * Noise.noise3(nx+0.5f, ny, time); 174 out[1] = y + amount * Noise.noise3(nx, ny+0.5f, time); 175 } else { 176 out[0] = x + amount * Noise.turbulence3(nx+0.5f, ny, turbulence, time); 177 out[1] = y + amount * Noise.turbulence3(nx, ny+0.5f, turbulence, time); 178 } 179 } 180 181 public String toString() { 182 return "Distort/Swim..."; 183 } 184}