#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}}