Browse Source

Merge pull request #20814 from Mugen87/dev44

GeometryUtils: Add gosper curve generator.
Mr.doob 4 years ago
parent
commit
cccaeb7fe4

+ 98 - 0
examples/js/utils/GeometryUtils.js

@@ -140,6 +140,104 @@ THREE.GeometryUtils = {
 		// Return complete Hilbert Curve.
 		return vec;
 
+	},
+
+	/**
+	 * Generates a Gosper curve (lying in the XY plane)
+	 *
+	 * https://gist.github.com/nitaku/6521802
+	 *
+	 * @param size The size of a single gosper island.
+	 */
+	gosper: function ( size ) {
+
+		size = ( size !== undefined ) ? size : 1;
+
+		function fractalize( config ) {
+
+			var output;
+			var input = config.axiom;
+
+			for ( var i = 0, il = config.steps; 0 <= il ? i < il : i > il; 0 <= il ? i ++ : i -- ) {
+
+				output = '';
+
+				for ( var j = 0, jl = input.length; j < jl; j ++ ) {
+
+					var char = input[ j ];
+
+					if ( char in config.rules ) {
+
+						output += config.rules[ char ];
+
+					} else {
+
+						output += char;
+
+					}
+
+				}
+
+				input = output;
+
+			}
+
+			return output;
+
+		}
+
+		function toPoints( config ) {
+
+			var currX = 0, currY = 0;
+			var angle = 0;
+			var path = [ 0, 0, 0 ];
+			var fractal = config.fractal;
+
+			for ( var i = 0, l = fractal.length; i < l; i ++ ) {
+
+				var char = fractal[ i ];
+
+				if ( char === '+' ) {
+
+					angle += config.angle;
+
+				} else if ( char === '-' ) {
+
+					angle -= config.angle;
+
+				} else if ( char === 'F' ) {
+
+					currX += config.size * Math.cos( angle );
+					currY += - config.size * Math.sin( angle );
+					path.push( currX, currY, 0 );
+
+				}
+
+			}
+
+			return path;
+
+		}
+
+		//
+
+		var gosper = fractalize( {
+			axiom: 'A',
+			steps: 4,
+			rules: {
+				A: 'A+BF++BF-FA--FAFA-BF+',
+				B: '-FA+BFBF++BF+FA--FA-B'
+			}
+		} );
+
+		var points = toPoints( {
+			fractal: gosper,
+			size: size,
+			angle: Math.PI / 3 // 60 degrees
+		} );
+
+		return points;
+
 	}
 
 };

+ 1 - 0
examples/jsm/utils/GeometryUtils.d.ts

@@ -5,4 +5,5 @@ import {
 export namespace GeometryUtils {
 	export function hilbert2D( center?: Vector3, size?: number, iterations?: number, v0?: number, v1?: number, v2?: number, v3?: number ): Vector3[];
 	export function hilbert3D( center?: Vector3, size?: number, iterations?: number, v0?: number, v1?: number, v2?: number, v3?: number, v4?: number, v5?: number, v6?: number, v7?: number ): Vector3[];
+	export function gosper( size?: number ): number[];
 }

+ 98 - 0
examples/jsm/utils/GeometryUtils.js

@@ -144,6 +144,104 @@ var GeometryUtils = {
 		// Return complete Hilbert Curve.
 		return vec;
 
+	},
+
+	/**
+	 * Generates a Gosper curve (lying in the XY plane)
+	 *
+	 * https://gist.github.com/nitaku/6521802
+	 *
+	 * @param size The size of a single gosper island.
+	 */
+	gosper: function ( size ) {
+
+		size = ( size !== undefined ) ? size : 1;
+
+		function fractalize( config ) {
+
+			var output;
+			var input = config.axiom;
+
+			for ( var i = 0, il = config.steps; 0 <= il ? i < il : i > il; 0 <= il ? i ++ : i -- ) {
+
+				output = '';
+
+				for ( var j = 0, jl = input.length; j < jl; j ++ ) {
+
+					var char = input[ j ];
+
+					if ( char in config.rules ) {
+
+						output += config.rules[ char ];
+
+					} else {
+
+						output += char;
+
+					}
+
+				}
+
+				input = output;
+
+			}
+
+			return output;
+
+		}
+
+		function toPoints( config ) {
+
+			var currX = 0, currY = 0;
+			var angle = 0;
+			var path = [ 0, 0, 0 ];
+			var fractal = config.fractal;
+
+			for ( var i = 0, l = fractal.length; i < l; i ++ ) {
+
+				var char = fractal[ i ];
+
+				if ( char === '+' ) {
+
+					angle += config.angle;
+
+				} else if ( char === '-' ) {
+
+					angle -= config.angle;
+
+				} else if ( char === 'F' ) {
+
+					currX += config.size * Math.cos( angle );
+					currY += - config.size * Math.sin( angle );
+					path.push( currX, currY, 0 );
+
+				}
+
+			}
+
+			return path;
+
+		}
+
+		//
+
+		var gosper = fractalize( {
+			axiom: 'A',
+			steps: 4,
+			rules: {
+				A: 'A+BF++BF-FA--FAFA-BF+',
+				B: '-FA+BFBF++BF+FA--FA-B'
+			}
+		} );
+
+		var points = toPoints( {
+			fractal: gosper,
+			size: size,
+			angle: Math.PI / 3 // 60 degrees
+		} );
+
+		return points;
+
 	}
 
 };

+ 2 - 92
examples/webgl_framebuffer_texture.html

@@ -40,6 +40,7 @@
 			import * as THREE from '../build/three.module.js';
 
 			import { OrbitControls } from './jsm/controls/OrbitControls.js';
+			import { GeometryUtils } from './jsm/utils/GeometryUtils.js';
 
 			let camera, scene, renderer;
 			let line, sprite, texture;
@@ -75,7 +76,7 @@
 
 				//
 
-				const points = generatePoints();
+				const points = GeometryUtils.gosper( 8 );
 
 				const geometry = new THREE.BufferGeometry();
 				const positionAttribute = new THREE.Float32BufferAttribute( points, 3 );
@@ -206,97 +207,6 @@
 
 			}
 
-			//
-
-			function generatePoints() {
-
-				// generate gosper curve (from https://gist.github.com/nitaku/6521802)
-
-				const gosper = fractalize( {
-					axiom: 'A',
-					steps: 4,
-					rules: {
-						A: 'A+BF++BF-FA--FAFA-BF+',
-						B: '-FA+BFBF++BF+FA--FA-B'
-					}
-				} );
-
-				const points = toPoints( {
-					fractal: gosper,
-					side: 8,
-					angle: Math.PI / 3
-				} );
-
-				return points;
-
-			}
-
-			function fractalize( config ) {
-
-				let output;
-				let input = config.axiom;
-
-				for ( let i = 0, il = config.steps; 0 <= il ? i < il : i > il; 0 <= il ? i ++ : i -- ) {
-
-					output = '';
-
-					for ( let j = 0, jl = input.length; j < jl; j ++ ) {
-
-						const char = input[ j ];
-
-						if ( char in config.rules ) {
-
-							output += config.rules[ char ];
-
-						} else {
-
-							output += char;
-
-						}
-
-					}
-
-					input = output;
-
-				}
-
-				return output;
-
-			}
-
-			function toPoints( config ) {
-
-				let currX = 0, currY = 0;
-				let angle = 0;
-				const path = [ 0, 0, 0 ];
-				const fractal = config.fractal;
-
-				for ( let i = 0, l = fractal.length; i < l; i ++ ) {
-
-					const char = fractal[ i ];
-
-					if ( char === '+' ) {
-
-						angle += config.angle;
-
-					} else if ( char === '-' ) {
-
-						angle -= config.angle;
-
-					} else if ( char === 'F' ) {
-
-						currX += config.side * Math.cos( angle );
-						currY += - config.side * Math.sin( angle );
-						path.push( currX, currY, 0 );
-
-					}
-
-				}
-
-				return path;
-
-			}
-
 		</script>
 
 	</body>