Die folgende Grafik wurde per JavaScript mit Hilfe des JSG3D-Moduls generiert. Beachte dass beim Verändern der Fenstergrösse die Grösse der Grafik automatisch neu berechnet und die Grafik neu gezeichnet wird.
var halfPlaneSpan = 6 * Math.PI; var numAreasPerLine = 150; var numAreasPerLine2 = 400; CreateHeart(); function DrawArrow( g3d ) { // Arrow in the background g3d.SetMarkerAttr( 'Arrow2', 14, 'black', 'black', 2 ); g3d.SetLineAttr( 'rgba(0,0,0,1)', 2 ); g3d.Arrow3D( [0,0,0], [0,20,0] ); } function DrawDecorations( g3d ) { // Axes and colored Lines var dxy = 2 * halfPlaneSpan / numAreasPerLine2; g3d.SetMarkerAttr( 'Arrow2', 14, 'black', 'black', 2 ); g3d.Arrow3D( [0,0,0], [15,0,0] ); g3d.Line3D( [0,0,0], [0,-20,0] ); g3d.Arrow3D( [0,0,0], [0,0,13] ); g3d.SetLineAttr( 'rgba(0,0,0,0.3)', 2 ); g3d.Arrow3D( [0,0,0], [0,20,0] ); var poly = g3d.PolygonFromFunc( { Func: function( x, p ) { return [ x, 0, Math.pow( x*x, 0.3 ) ]; }, Min: 0, Max: halfPlaneSpan, Steps: numAreasPerLine2/2 } ); g3d.SetLineAttr( 'yellow', 2 ); g3d.Polygon3D( poly ); var poly = g3d.PolygonFromFunc( { Func: function( x, p ) { var z = Math.pow( Math.sin( 15 * Math.pow( ell(x,0), 0.1 ) ), 2 ) * 1 * Math.pow( x*x, 0.3 ); return [ x, 0, z ]; }, Min: 0, Max: halfPlaneSpan, Steps: numAreasPerLine2/2 } ); g3d.SetLineAttr( 'blue', 3.5 ); g3d.Polygon3D( poly ); g3d.SetTextAttr( 'Arial', 18, 'black', 'bold', 'normal', 'center', 'middle' ); var offset = 1; g3d.Text3D( 'X', [15+offset,0,0] ); g3d.Text3D( 'Y', [0,20+offset,0] ); g3d.Text3D( 'Z', [0,0,13+offset] ); } function CreateHeart() { // Init 3D module and create 3D graphic var g3d = NewGraph3D( { BeforeDrawFunc: DrawArrow, AfterDrawFunc: DrawDecorations, SceneSize: 2*halfPlaneSpan, ScaleRef: 800, AutoScalePix: true, CamViewCenter: JsgVect3.New(2.5,2.5,2), CamHAng: -75, CamVAng: 35, CamDist: 150, Zoom: 1.7, Aperture: 0.9 } ); // define the various area attributes and lighting var data1 = new JsgEleData( { AreaDrawMode: 3, AreaAttrFunc: AreaColorChanger, Lighting: { ApplyCamLight: false, ApplyPhong: false, ApplyAmbient: false }, BackLighting: { Dimm: 0.9 } } ); var data2 = new JsgEleData( { AreaDrawMode: 2, AreaAttrFunc: AreaColorChanger, Lighting: { ApplyCamLight: true, ApplyPhong: true, ApplyAmbient: true, CamRefl: 0.2, AmbiRefl: 0.05, DiffRefl: 0.5, SpecRefl: 1, Shiny: 8, DiffXRay: 1, SpecXRay: 1 }, BackLighting: { Dimm: 0.9 } } ); var data3 = new JsgEleData( { AreaDrawMode: 3, Attr: { AreaColor: JsgColor.BW(2), AreaBackColor: JsgColor.White(), LineColor: JsgColor.BW(0.5), AreaBackLineColor: JsgColor.BW(0.25), LineWidth: 1 }, Lighting: { ApplyCamLight: false, ApplyPhong: false, ApplyAmbient: false }, BackLighting: { Dimm: 0.9 } } ); g3d.SetAmbientLight( JsgColor.White() ); g3d.SetCameraLight( JsgColor.White() ); g3d.AddLightSource( { LightColor: JsgColor.White(), DiffInt: 0.4, SpecInt: 0.9, LightDir: JsgVect3.New(20,50,100) } ); g3d.AddLightSource( { LightColor: JsgColor.RGB(1,1,0.8), DiffInt: 0.9, SpecInt: 1, LightPos: JsgVect3.New(-10,-10,10) } ); g3d.AddLightSource( { LightColor: JsgColor.RGB(0.4,0.4,1), DiffInt: 0.5, SpecInt: 1, LightPos: JsgVect3.New(10,10,10) } ); g3d.AddAreasFromVectGrid( CreateVectGrid( -halfPlaneSpan, 0, 0, halfPlaneSpan, numAreasPerLine ), data1 ); g3d.AddAreasFromVectGrid( CreateVectGrid( 0, halfPlaneSpan, 0, halfPlaneSpan, numAreasPerLine2 ), data2 ); g3d.AddAreasFromVectGrid( CreateVectGrid( -halfPlaneSpan, 0, -halfPlaneSpan, 0, numAreasPerLine ), data3 ); } function AreaColorChanger( g3d, aArea, aAreaAttr ) { var c = g3d.GraphEleCenter( aArea ); var r = Math.pow( ell( c[0], c[1] ), 0.1 ); var val = 1-Math.pow( Math.sin( 15 * r ), 2 ); if (r > Math.PI/2) { if (r > 1.05*Math.PI/2) { var alpha = Math.exp( - Math.pow( 15 * (r - (1.04 * Math.PI/2)), 4 ) ); JsgColor.SetRGBA( aAreaAttr.AreaColor, 1, val, 0, alpha ); JsgColor.SetRGBA( aAreaAttr.AreaBackColor, 1, val, 0, alpha ); JsgColor.SetRGBA( aAreaAttr.LineColor, 1, val, 0, alpha ); JsgColor.SetRGBA( aAreaAttr.AreaBackLineColor, 1, val, 0, alpha ); } else { JsgColor.SetRGB( aAreaAttr.AreaColor, 1, val, 0 ); JsgColor.SetRGB( aAreaAttr.AreaBackColor, 1, val, 0 ); JsgColor.SetRGB( aAreaAttr.LineColor, 1, val, 0 ); JsgColor.SetRGB( aAreaAttr.AreaBackLineColor, 1, val, 0 ); } } else { JsgColor.SetRGB( aAreaAttr.AreaColor, 1, val, val ); JsgColor.SetRGB( aAreaAttr.AreaBackColor, 1, val, val ); JsgColor.SetRGB( aAreaAttr.LineColor, 1, val, val ); JsgColor.SetRGB( aAreaAttr.AreaBackLineColor, 1, val, val ); } } function CreateVectGrid( XStart, XEnd, YStart, YEnd, resolution ) { var dxy = 2 * halfPlaneSpan / resolution; var dxy2 = dxy / 2; var grid = []; for (var y = YStart; y <= YEnd+dxy2; y += dxy) { var line = []; for (var x = XStart; x <= XEnd+dxy2; x += dxy) { var z = Math.pow( Math.sin( 15 * Math.pow( ell(x,y), 0.1 ) ), 2 ) * 1 * Math.pow( x*x + y*y, 0.3 ); line.push( [ x, y, z ] ); } grid.push( line ); } return grid; } function ell( x, y ) { return x*x - 1.2*Math.abs(x)*y + y*y; }