#INCLUDE JsGraph.inc #INCLUDE ControlPanel.inc <jscript> function SplineModel() { this.Trans = 'window'; this.InRect = false; this.InPath = false; this.Append = false; this.Close = true; this.Stroke = true; this.Fill = false; this.Invert = false; this.SkipStart = false; this.SkipEnd = false; this.SplineEnds = false; this.ShowPoints = true; this.ShowControl = true; this.Width = 4; this.Size = 0.75; this.Cap = 'but'; this.Tension = 0.5; this.LastNPoints = 4; this.NPoints = 4; this.PolyTemplate = new JsgPolygon(); this.Poly = new JsgPolygon(); this.MakePoly(); this.Update(); } SplineModel.prototype.MakePoly = function() { this.PolyTemplate.Reset(); for (var i = 0; i < this.NPoints; i++ ) { this.PolyTemplate.AddPoint( Math.random(), Math.random() ); } } SplineModel.prototype.Update = function() { this.Poly.Reset(); var w = this.Size * 600; var h = this.Size * 400; for (var i = 0; i < this.NPoints; i++) { var x = this.PolyTemplate.X[i] * w + 0.5 * (600-w); var y = this.PolyTemplate.Y[i] * h + 0.5 * (400-h); this.Poly.AddPoint( x, y ); } } var model = new SplineModel(); var jsg = NewGraph2D( { Width: 602, Height: 403, DrawFunc: Draw, AutoReset: false } ); function Draw( g ) { g.Reset(); g.SetLineCap( model.Cap ); g.SetWindowWH( 0, 0, g.VpInnerWidth, g.VpInnerHeight ); g.SelectTrans( model.Trans ); g.SetAreaAttr( 'orange', 'blue', model.Width ); var mode = 0; if (model.Stroke) mode += 1; if (model.Fill) mode += 2; if (model.Close) mode += 4; if (model.Append) mode += 8; if (model.SkipStart) mode += 16; if (model.SkipEnd) mode += 32; if (model.SplineEnds) mode += 64; if (model.SymmetricControls) mode += 128; if (model.InPath) { g.OpenPath(); } if (model.InRect) g.Rect( 50, 50, 550, 350 ); if (model.Invert) model.Poly.Invert(); var wpoly = g.SplineCurve( model.Poly, model.Tension, mode ); var bezier = wpoly.Copy(); if (model.Invert) model.Poly.Invert(); if (model.InPath) g.Path( mode ); g.Polygon( [ 0, 0, 10 ], [ 10, 0, 0 ] ); if (model.ShowControl && !model.Append) { g.SetLineAttr( 'gray', 1 ); var last = bezier.Size - 1; for (var i = 0; i <= last; i += 3) { if (i > 0) g.Line( bezier.X[i-1], bezier.Y[i-1], bezier.X[i], bezier.Y[i] ); if (i < last) g.Line( bezier.X[i], bezier.Y[i], bezier.X[i+1], bezier.Y[i+1] ); } g.SetMarkerAttr( 'Square', 7, 'gray', 'white', 1 ); g.Marker( bezier, 3 ); } if ((model.ShowPoints || model.ShowControl) && !model.Append) { g.SetMarkerAttr( 'Circle', 13, 'black', 'yellow', 1 ); g.Marker( model.Poly ); } } function Update() { if (model.LastNPoints != model.NPoints) { model.MakePoly(); model.LastNPoints = model.NPoints; } model.Update(); panel1.Update(); panel2.Update(); Draw( jsg ); } function NewSpline() { model.MakePoly(); Update(); } </jscript> {{col|50}} <jscript> var panel1 = ControlPanels.NewSliderPanel( { ModelRef: 'model', OnModelChange: Update } ); panel1.AddValueSliderField( { Name: 'NPoints', Min: 3, Max: 20, Steps: 17, Digits: 0 } ); panel1.AddValueSliderField( { Name: 'Size', Min: 0.1, Max: 1, Digits: 2 } ); panel1.AddValueSliderField( { Name: 'Tension', Min: -2, Max: 2, Digits: 2 } ); panel1.AddValueSliderField( { Name: 'Width', Min: 0, Max: 20, Digits: 1 } ); panel1.Render(); </jscript> {{col}} <jscript> var panel2 = ControlPanels.NewPanel( { ModelRef: 'model', OnModelChange: Update } ); panel2.AddRadiobuttonField( { Name: 'Trans', Items: [ { Name: 'window' }, { Name: 'viewport' }, { Name: 'canvas' } ] }); panel2.AddRadiobuttonField( { Name: 'Cap', Items: [ { Name: 'but' }, { Name: 'round' }, { Name: 'square' } ] } ); panel2.AddCheckboxField( { Name: 'Mode', Items: [ { Name: 'Stroke' }, { Name: 'Fill' }, { Name: 'Close' }, { Name: 'Append' } ] } ); panel2.AddCheckboxField( { Name: 'Path', Items: [ { Name: 'InRect' }, { Name: 'InPath' }, { Name: 'Invert' }, ] } ); panel2.AddCheckboxField( { Name: 'Show', Items: [ { Name: 'ShowPoints' }, { Name: 'ShowControl' } ] } ); panel2.AddCheckboxField( { Name: 'Control', NCols: 2, Items: [ { Name: 'SkipStart' }, { Name: 'SkipEnd' }, { Name: 'SplineEnds' }, { Name: 'SymmetricControls' } ] } ); panel2.AddHtmlField( { Label: '-', Html: ControlPanels.SmallButton( 'New Spline', 'NewSpline()' ) } ); panel2.Render(); </jscript> {{col|end}}