Results 1 to 6 of 6

Thread: 3d textured rotating sphere in javascript

  1. #1
    Join Date
    Oct 2007
    Posts
    1
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default 3d textured rotating sphere in javascript

    I'm looking to make a 3d textured sphere in javascript. it needs to rotate at a constant rate and have the 'camera' positioned in it's center so the texture needs to be applied to the inside surface. any tips, scripts, or somewhat related scripts would help a lot. I also need to put div's with content over it. But I can do that much. I've used javascript for a lot of things due to it's portability, but this would be my first venture into using it to render 3d stuff since the debut of the html 4.0 spec.

  2. #2
    Join Date
    Mar 2006
    Location
    Illinois, USA
    Posts
    12,164
    Thanks
    265
    Thanked 690 Times in 678 Posts

    Default

    Heh. Nope. The end.
    you could, I imagine, try to fake it with a circular gradient as the highlight within the bounds of a circle.
    But you can't do even a circle in JS, much less a sphere that can rotate.
    3D space does not exist in JS except for the z-index (depth of 'layer').

    Flash or Java applets (NOT the same as javascript) are what you'd need here.

    I've seen some impressive cubes that are faked with JS, but that's only because of basic math operations to fake all of the "sides".
    A sphere's math would be more complex, not work the same way, be nearly impossible to display due to curves and, if you did get it working, you'd probably crash the browser anyway... it would need to be individual pixel-sized elements, when it comes down to it.
    Daniel - Freelance Web Design | <?php?> | <html>| español | Deutsch | italiano | português | català | un peu de français | some knowledge of several other languages: I can sometimes help translate here on DD | Linguistics Forum

  3. #3
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,876
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default

    I've seen some impressive cubes that are faked with JS, but that's only because of basic math operations to fake all of the "sides".
    "Faked?" Everything 3D we see on a 2D computer monitor is "faked." In this case, it's perfectly possible to do (if insanely complex). Look into the <canvas> element. Mozilla's upcoming Canvas3D actually has an element dedicated to producing spheres.
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends français | entiendo español | tôi ít hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

  4. #4
    Join Date
    Mar 2006
    Location
    Illinois, USA
    Posts
    12,164
    Thanks
    265
    Thanked 690 Times in 678 Posts

    Default

    Faked in the sense that the methods used are being [mis]used to do something for which they were not designed. It's a trick, not a feature.
    Only possible as a representation of pixels, within the limits that javascript presents.

    The other possibilities mentioned may be fun to play with and/or full of potential, but they don't actually work yet [mostly], and a certainly not compatible with all browsers. When will IE allow the <sphere> object? So... nope.

    Considering the idea is to have a working script, not a theoretical possibility, I'm sticking with no.
    Daniel - Freelance Web Design | <?php?> | <html>| español | Deutsch | italiano | português | català | un peu de français | some knowledge of several other languages: I can sometimes help translate here on DD | Linguistics Forum

  5. #5
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,876
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default

    Faked in the sense that the methods used are being [mis]used to do something for which they were not designed. It's a trick, not a feature.
    Then you mean a "hack."
    The other possibilities mentioned may be fun to play with and/or full of potential, but they don't actually work yet [mostly], and a certainly not compatible with all browsers. When will IE allow the <sphere> object?
    <canvas> is supported by most browsers (Firefox, Safari, Opera), and can be (and has been) used to create a slow but functional 3D renderer. IE has VML, which I believe supports 3D natively.
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends français | entiendo español | tôi ít hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

  6. #6
    Join Date
    May 2007
    Location
    USA
    Posts
    373
    Thanks
    2
    Thanked 4 Times in 4 Posts

    Default

    Even though it would not be much more difficult to implement in Javascript than something like java, do not use Javascript. The task you are describing would be way, way too slow if you programmed in in JS. Use a Java applet instead.

    My gut says to use a cylindrical coordinate system to set up each pixel.
    http://en.wikipedia.org/wiki/Cylindrical_coordinates
    (Here's an applet that might help you understand it: http://www.pha.jhu.edu/~javalab/cyli...lindrical.html)

    I've made a sphere and other "3D" designs before using said method using Java, albeit not rotating. Here's the code... it might be insightful.
    Code:
    import java.awt.*;
    import java.awt.image.*;
    
    public class Gradient {
    	
    	public static final int NONE = -1;
    	public static final int LINEAR = 0;
    	public static final int LINEAR_IN_OUT = 1;
    	public static final int CIRCLE = 2;
    	public static final int STARBURST = 3;
    	public static final int RADIATE = 4;
    	
    	private static BufferedImage bimg;
    	
    	private Gradient(){}
    	
    	public static void createGradient(BufferedImage bimg, int gradientType, Color start, Color end) {
    		int w = bimg.getWidth();
    		int h = bimg.getHeight();
    		createGradient(bimg, gradientType, start, end, 0, 0, 0.0, Double.MAX_VALUE);
    	}
    	public static void createGradient(BufferedImage bimg, int gradientType, Color start, Color end, int cX, int cY, double rotate) {
    		int w = bimg.getWidth();
    		int h = bimg.getHeight();
    		createGradient(bimg, gradientType, start, end, cX, cY, rotate, Double.MAX_VALUE);
    	}
    	public static void createGradient(BufferedImage bimg, int gradientType, Color start, Color end, int cX, int cY, double rotate, double rMax) {
    		Gradient.bimg = bimg;
    		int w = bimg.getWidth();
    		int h = bimg.getHeight();
    		if(gradientType==NONE) {
    			int clear = new Color(0, 0, 0, 0).getRGB();
    			for(int i=0; i<w; ++i)
    				for(int j=0; j<h; ++j)
    					bimg.setRGB(i, j, clear);
    			return;
    		}
    		double r;
    		double[][] rs = new double[w][h];
    		double th, thMax = Math.PI*2, thInc = thMax/5000;
    		int xIndex = 0, yIndex;
    		double[][] zs = new double[w][h];
    		double z, zMin = 0, zMax = 0;
    		int[] colors = new int[256];
    		{
    			double red = start.getRed();
    			double green = start.getGreen();
    			double blue = start.getBlue();
    			double alpha = start.getAlpha();
    			double redInc = (end.getRed() - red) / 256.0;
    			double greenInc = (end.getGreen() - green) / 256.0;
    			double blueInc = (end.getBlue() - blue) / 256.0;
    			double alphaInc = (end.getAlpha() - alpha) / 256.0;
    			for(int i=0, n=colors.length; i<n; ++i) {
    				colors[i] = new Color(
    						(int)Math.round(red+redInc), 
    						(int)Math.round(green+greenInc), 
    						(int)Math.round(blue+blueInc), 
    						(int)Math.round(alpha+alphaInc)
    						).getRGB();
    				red += redInc;
    				green += greenInc;
    				blue += blueInc;
    				alpha += alphaInc;
    			}
    		}
    		double[] colorBreakpts = new double[colors.length];
    		for(double x=-w/2-cX; x<w/2-cX; ++x, ++xIndex) {
    			yIndex = h-1;
    			for(double y=-w/2-cY; y<w/2-cY; ++y, --yIndex) {
    				r = Math.sqrt(x*x + y*y);
    				rs[xIndex][yIndex] = r;
    				if(r>rMax) continue;
    				th = normalizeAngle(Math.atan2(y, x) - rotate);
    				z = getZValue(r, th, gradientType);
    				zs[xIndex][yIndex] = z;
    				if(z<zMin) zMin = z;
    				else if(z>zMax) zMax = z;
    			}
    		}
    		double zInc = (zMax-zMin)/colorBreakpts.length;
    		z = zMin;
    		for(int i=0, n=colorBreakpts.length; i<n; ++i) {
    			z += zInc;
    			colorBreakpts[i] = z;
    		}
    		for(int x=0; x<w; ++x) {
    			for(int y=0; y<h; ++y) {
    				if(rs[x][y]<=rMax) {
    					z = zs[x][y];
    					for(int i=0, n=colorBreakpts.length; i<n; ++i) {
    						if(z<=colorBreakpts[i]) {
    							bimg.setRGB(x, y, colors[i]);
    							break;
    						}
    					}
    				}
    				else bimg.setRGB(x, y, Color.BLACK.getRGB());
    			}
    		}
    	}
    	
    	private static double getZValue(double r, double th, int gradientType) {
    		switch(gradientType) {
    		case CIRCLE: 
    			return circle(r, th);
    		case LINEAR:
    			return linear(r, th);
    		case LINEAR_IN_OUT:
    			return linearInOut(r, th);
    		case STARBURST:
    			//need to make this function
    		case RADIATE:
    			return radiate(r, th);
    		}
    		assert false;
    		return 0.0;
    	}
    	
    	private static double normalizeAngle(double th) {
    		while(th>=Math.PI*2) th -= Math.PI*2;
    		while(th<0) th += Math.PI*2;
    		return th;
    	}
    	
    	private static double linear(double r, double th) {
    		return (r*Math.cos(th)-r*Math.sin(th));
    	}
    	
    	private static double linearInOut(double r, double th) {
    		if(th>Math.PI/4 && th<=Math.PI*5/4)
    			return (r*Math.cos(th)-r*Math.sin(th));
    		return -(r*Math.cos(th)-r*Math.sin(th));
    	}
    	
    	private static double circle(double r, double th) {
    		return -Math.pow(r, 3/2);
    	}
    	
    	private static double radiate(double r, double th) {
    		return Math.min(Math.abs(th-Math.PI/4+0.01), Math.abs(th-Math.PI*7/4-0.01));
    	}
    }
    Trinithis

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •