Permalink
Browse files

Basically correct scaling calculations, scale transition gradient

  • Loading branch information...
1 parent de5ba97 commit 846690f41e644b84759ca11ee0ac66bd7aa17123 @ahk ahk committed Mar 5, 2012
View
@@ -36,14 +36,15 @@
<div id='canvas-title'>
DOMEKIT DRAWING SURFACE ENVISIONED
</div>
- <div id='canvas-goes-here'>
+ <div id='canvas-goes-here' style="border: 1px solid red">
</div>
<div id="dome-sphere-controls">
<div id="choose-a-dome" style="background-color: #aaa; width: 3em; height: 3em;">Dome</div>
<div id="choose-a-sphere" style="background-color: #aaa; width: 3em; height: 3em;">Sphere</div>
</div>
- Scale:
- <div id="scale-slider-goes-here"></div>
+ Radius (feet):
+ <div id="radius-slider-goes-here"></div>
+ <div id="radius-slider-value"></div>
<script>
window.onload = function() {
var demo = new domekit.Demo();
View
@@ -32,12 +32,27 @@ domekit.EventType = {
domekit.Controller = function(opts) {
goog.base(this);
- this.scale_ = opts.scale || 1.0;
+ this.scale_ = opts.scaleMin || 1.0;
+ this.scaleMin_ = opts.scaleMin || 1.0;
+ this.scaleMax_ = opts.scaleMax || 1.0;
+
this.triangleFrequency_ = opts.freq || 2;
+ this.context_ = null;
this.canvasWidth_ = opts.width || 500;
this.canvasHeight_ = opts.height || 500;
+ // actual 2d pixels height and width of geodesic
+ this.projectionHeight_ = null;
+ this.projectionWidth_ = null;
+ // how tall the dome is compared to the sphere
+ this.domeVProportion_ = null;
+ // related to domeVProportion_
+ this.domeHeightFeet_ = null;
+ this.sphereHeightFeet_ = null;
+
+ this.radiusMin_ = opts.radiusMin || 1 // feet
+ this.radiusMax_ = opts.radiusMax || 500
+ this.radius_ = this.radiusMax_
- this.context_ = null;
this.clipDome_ = true;
this.enableClipZ_ = false;
this.clipY_ = 0.5;
@@ -55,16 +70,15 @@ domekit.Controller = function(opts) {
// [i] == true if connections[i] contains only visible points
this.visibleConnections_ = [];
- this.scaleIconInfo_ = {
- maxX: 56,
- maxY: 150
- };
this.scaleIcon_ = new domekit.ScaleIcon(
- new goog.math.Size(this.scaleIconInfo_.maxX,
- this.scaleIconInfo_.maxY)
+ {
+ feet: this.radiusMax_ * 2, // full sphere height
+ pixels: this.canvasHeight_
+ },
+ new goog.math.Size(56, 150)
);
- this.calculateProjectionDimensions();
+ this.updateProjectionDimensions();
};
goog.inherits(domekit.Controller, goog.ui.Component);
@@ -170,17 +184,17 @@ domekit.Controller.prototype.project = function(xy, z, zCameraOffset, zDepth, xy
domekit.Controller.prototype.projectPoints = function() {
var newPoint,
- xOffset = this.offsets.x,
- yOffset = this.offsets.y,
- points = this.points_;
+ xOffset = this.offsets_.x,
+ yOffset = this.offsets_.y,
+ points = this.points_;
this.projectedPoints_ = [];
for (var i = 0; i < points.length; i++) {
if (this.visiblePoints_[i]) {
// visible points are projected
newPoint = this.projectedPoints_[i] = new domekit.Point3D();
- newPoint.x = this.project(points[i].x, points[i].z, 2.2, .005, xOffset, this.scale_);
- newPoint.y = this.project(points[i].y, points[i].z, 2.2, .005, yOffset, this.scale_);
+ newPoint.x = this.project(points[i].x, points[i].z, 2.0, .005, xOffset, this.scale_);
+ newPoint.y = this.project(points[i].y, points[i].z, 2.0, .005, yOffset, this.scale_);
newPoint.z = points[i].z;
} else {
// invisible points are null in the projection
@@ -278,7 +292,7 @@ domekit.Controller.prototype.clipToVisiblePoints = function() {
domekit.Controller.prototype.setDomeMode = function() {
this.clipDome_ = true;
this.scaleIcon_.setFloor(this.calculateFloor());
- this.calculateProjectionDimensions();
+ this.updateProjectionDimensions();
goog.events.dispatchEvent(this, domekit.EventType.GEOMETRY_CHANGE);
this.renderView();
@@ -287,7 +301,7 @@ domekit.Controller.prototype.setDomeMode = function() {
domekit.Controller.prototype.setSphereMode = function() {
this.clipDome_ = false;
this.scaleIcon_.setCenter(this.calculateCenter());
- this.calculateProjectionDimensions();
+ this.updateProjectionDimensions();
goog.events.dispatchEvent(this, domekit.EventType.GEOMETRY_CHANGE);
this.renderView();
@@ -302,7 +316,7 @@ domekit.Controller.prototype.setTriangleFrequency = function(frequency) {
this.triangleFrequency_ = frequency;
this.setClip();
this.generateModelPointsAndConnections();
- this.calculateProjectionDimensions();
+ this.updateProjectionDimensions();
//this.rotateY(Math.PI / 32);
//this.rotateX(Math.PI / 48);
this.strutLengths();
@@ -325,45 +339,84 @@ domekit.Controller.prototype.setClip = function() {
else {this.clipY_ = .2; this.clipZ_ = -Math.PI / 10;}
};
+domekit.Controller.prototype.updateScaleIconCompareHeight = function() {
+ var pixels = this.projectionHeight_
+
+ if (this.clipDome_) {
+ this.scaleIcon_.setCompareHeight({
+ feet: this.domeHeightFeet_,
+ pixelsToFeet: pixels / this.sphereHeightFeet_
+ })
+ } else {
+ this.scaleIcon_.setCompareHeight({
+ feet: this.sphereHeightFeet_,
+ pixelsToFeet: pixels / this.sphereHeightFeet_
+ })
+ }
+
+}
+
// scale is specified 0.0 - 1.0
domekit.Controller.prototype.setScale = function(scale) {
- var iconDomeScaleRatio = 0.9;
- var iconScale = 1 - (scale * iconDomeScaleRatio);
- this.scaleIcon_.setSize(
- new goog.math.Size(
- this.scaleIconInfo_.maxX * iconScale,
- this.scaleIconInfo_.maxY * iconScale));
this.scale_ = scale;
-
+ this.updateProjectionDimensions()
goog.events.dispatchEvent(this, domekit.EventType.GEOMETRY_CHANGE);
this.renderView();
};
+domekit.Controller.prototype.updateScaleAndGradient = function() {
+ // a linear transition
+ var gradientPosition = this.radius_ - this.radiusMin_
+ var gradientLength = this.radiusMax_ - this.radiusMin_
+ var gradientValue = gradientPosition / gradientLength;
+ var scaleLength = this.scaleMax_ - this.scaleMin_
+ var scale = gradientValue * scaleLength + this.scaleMin_;
-domekit.Controller.prototype.calculateProjectionDimensions = function() {
- this.projectionWidth_ = this.canvasWidth_;
- this.projectionHeight_ = this.canvasHeight_;
+ this.scale_ = scale;
+
+ this.projectionWidth_ = this.canvasWidth_ * this.scale_;
+ this.projectionHeight_ = this.canvasHeight_ * this.scale_;
+}
+
+domekit.Controller.prototype.setRadius = function(feet) {
+ this.radius_ = feet
+ var sphereHeight = this.sphereHeightFeet_ = 2 * feet
+ if (this.clipDome_) {
+ this.domeHeightFeet_ = sphereHeight * this.domeVProportion_
+ } else {
+ this.domeHeightFeet_ = sphereHeight
+ }
+ this.updateProjectionDimensions()
+ goog.events.dispatchEvent(this, domekit.EventType.GEOMETRY_CHANGE);
+ this.renderView();
+}
+
+domekit.Controller.prototype.updateProjectionDimensions = function() {
+
+ // number of triangles (divisions) rotation around a circle?
var domeVOffset = Math.cos(
Math.ceil(this.triangleFrequency_ * 3.0 / 2.0) /
(this.triangleFrequency_ * 3.0) * Math.PI
) / 2.0 + .5;
+ this.domeVProportion_ = 1 - domeVOffset
if (this.clipDome_) {
this.maximumRadius_ = Math.min(this.canvasWidth_, this.canvasHeight_) / 2;
- this.offsets = {
- x: this.projectionWidth_ / 2,
- y: this.projectionHeight_ / 2 + domeVOffset * this.projectionHeight_ - 40
+ this.offsets_ = {
+ x: this.canvasWidth_ / 2,
+ y: this.canvasHeight_ / 2 + domeVOffset * this.canvasHeight_ - 5
};
- // FIXME: Why is this here?
- if (this.triangleFrequency_ == 1) this.offsets.y += 13;
} else {
- this.maximumRadius_ = (Math.min(this.canvasWidth_, this.canvasHeight_) / 2) - 20;
- this.offsets = {
- x: this.projectionWidth_ / 2,
- y: this.projectionHeight_ / 2
+ this.maximumRadius_ = (Math.min(this.canvasWidth_, this.canvasHeight_) / 2);
+ this.offsets_ = {
+ x: this.canvasWidth_ / 2,
+ y: this.canvasHeight_ / 2
};
}
+
+ this.updateScaleAndGradient();
+ this.updateScaleIconCompareHeight()
};
domekit.Controller.prototype.calculateFloor = function() {
View
@@ -5,25 +5,35 @@ goog.require('goog.ui.Slider');
/** @constructor */
domekit.Demo = function() {
- var domekitController = new domekit.Controller({
- width: 600, height: 600});
+ var domeOpts = {
+ width: 500,
+ height: 500,
+ scaleMin: 0.7,
+ scaleMax: 1.0,
+ radiusMin: 1,
+ radiusMax: 500
+ };
+ var domekitController = new domekit.Controller(domeOpts);
var goesHere = document.getElementById('canvas-goes-here');
// begin drawing dome canvas component
domekitController.render(goesHere);
// scale slider
- var scaleSlider = new goog.ui.Slider();
- scaleSlider.render(
- document.getElementById('scale-slider-goes-here')
+ var radiusSlider = new goog.ui.Slider();
+ radiusSlider.render(
+ document.getElementById('radius-slider-goes-here')
);
- var scaleSliderMaxVal = 100;
- scaleSlider.setMaximum(scaleSliderMaxVal);
- scaleSlider.addEventListener(goog.ui.Component.EventType.CHANGE, function() {
- var scale = scaleSlider.getValue() / scaleSliderMaxVal;
- domekitController.setScale(scale);
+ var radiusSliderMaxVal = domeOpts.radiusMax;
+ var radiusSliderMinVal = domeOpts.radiusMin;
+ radiusSlider.setMaximum(radiusSliderMaxVal);
+ radiusSlider.setMinimum(radiusSliderMinVal);
+ radiusSlider.addEventListener(goog.ui.Component.EventType.CHANGE, function() {
+ var height = radiusSlider.getValue();
+ domekitController.setRadius(height);
+ goog.dom.setTextContent(document.getElementById('radius-slider-value'), '' + height)
});
- scaleSlider.setValue(0.5 * scaleSliderMaxVal);
- domekitController.setScale(0.5);
+ //default
+ radiusSlider.setValue(6); // HUMAN SIZED
// dome mode button
var domeButton = goog.dom.getElement('choose-a-dome');
View
@@ -70,9 +70,9 @@ domekit.RadiusControl = function(controller) {
this.controller_ = controller;
this.radiusInput_ = new goog.ui.LabelInput();
this.radiusSlider_ = new goog.ui.Slider();
- this.minRadius_ = 0; // percent
- this.maxRadius_ = 100;
- this.defaultRadius_ = this.maxRadius_ * this.controller_.getScale();
+ this.minRadius_ = 1; // feet
+ this.maxRadius_ = 500;
+ this.defaultRadius_ = 6 // HUMAN SIZED
this.radiusUnitsAbbrv_ = domekit.RadiusUnits.FEET;
};
goog.inherits(domekit.RadiusControl, goog.ui.Component);
@@ -96,61 +96,40 @@ domekit.RadiusControl.prototype.enterDocument = function() {
this.radiusSlider_.setMinimum(this.minRadius_);
this.radiusSlider_.setValue(this.defaultRadius_);
- this.controller_.setScale(this.defaultRadius_ / this.maxRadius_);
+ this.controller_.setRadius(this.defaultRadius_);
this.radiusSlider_.addEventListener(goog.ui.Component.EventType.CHANGE,
goog.bind(function() {
var sliderVal = this.radiusSlider_.getValue();
this.updateRadiusInput(sliderVal);
- this.controller_.setScale(sliderVal / this.maxRadius_);
+ this.controller_.setRadius(sliderVal);
}, this)
);
+ var handleInputChange = goog.bind(function() {
+ var textVal = this.radiusInput_.getValue();
+ textVal = textVal.replace(new RegExp(this.radiusUnitsAbbrv_, 'i'), '');
+ var num = goog.string.toNumber(textVal);
+ if (num === NaN) {
+ this.updateRadius(this.defaultRadius_);
+ } else if (num > this.maxRadius_) {
+ this.updateRadius(this.maxRadius_);
+ } else if (num < this.minRadius_) {
+ this.updateRadius(this.minRadius_);
+ } else {
+ this.updateRadius(num);
+ }
+ }, this)
+
// this is a hack. I have no idea why goog.ui.LabelInput,
// which is a goog.ui.Component, doesn't throw events of the Component
// enum
- goog.events.listen(this.radiusInput_.getElement(), 'change',
- goog.bind(function() {
- var textVal = this.radiusInput_.getValue();
- textVal = textVal.replace(new RegExp(this.radiusUnitsAbbrv_, 'i'), '');
- var num = goog.string.toNumber(textVal);
- var pct = this.convertDistanceToPct(num);
- if (pct === NaN) {
- this.updateRadius(this.defaultRadius_);
- } else if (pct > this.maxRadius_) {
- this.updateRadius(this.maxRadius_);
- } else if (pct < this.minRadius_) {
- this.updateRadius(this.minRadius_);
- } else {
- this.updateRadius(pct);
- }
- }, this)
- );
-};
-
-domekit.RadiusControl.prototype.convertPctToDistance = function(pct) {
- var maxM = 204;
- var maxF = 713;
- if (this.radiusUnitsAbbrv_ === domekit.RadiusUnits.METERS) {
- return (pct / this.maxRadius_) * maxM;
- } else if (this.radiusUnitsAbbrv_ === domekit.RadiusUnits.FEET) {
- return (pct / this.maxRadius_) * maxF;
- }
-};
-
-domekit.RadiusControl.prototype.convertDistanceToPct = function(distance) {
- var maxM = 204;
- var maxF = 713;
- if (this.radiusUnitsAbbrv_ === domekit.RadiusUnits.METERS) {
- return (distance / maxM) * this.maxRadius_;
- } else if (this.radiusUnitsAbbrv_ === domekit.RadiusUnits.FEET) {
- return (distance / maxF) * this.maxRadius_;
- }
+ goog.events.listen(this.radiusInput_.getElement(), 'change', handleInputChange);
};
-domekit.RadiusControl.prototype.updateRadius = function(pct) {
- this.updateRadiusInput(pct);
- this.radiusSlider_.setValue(pct);
- this.controller_.setScale(pct / this.maxRadius_);
+domekit.RadiusControl.prototype.updateRadius = function(radius) {
+ this.updateRadiusInput(radius);
+ this.radiusSlider_.setValue(radius);
+ this.controller_.setRadius(radius);
};
/**
@@ -161,9 +140,8 @@ domekit.RadiusControl.prototype.setRadiusUnits = function(units) {
this.updateRadius(sliderVal);
};
-domekit.RadiusControl.prototype.updateRadiusInput = function(pct) {
- var distance = this.convertPctToDistance(pct);
- this.radiusInput_.setValue(distance + this.radiusUnitsAbbrv_);
+domekit.RadiusControl.prototype.updateRadiusInput = function(radius) {
+ this.radiusInput_.setValue(radius + this.radiusUnitsAbbrv_);
};
/** @constructor
@@ -292,7 +270,10 @@ domekit.Generator = function() {
var domekitController = new domekit.Controller({
width: 600,
height: 350,
- scale: 1.0
+ scaleMin: 0.7,
+ scaleMax: 1.0,
+ radiusMin: 1,
+ radiusMax: 500
});
var goesHere = document.getElementById('scaledview');
Oops, something went wrong.

0 comments on commit 846690f

Please sign in to comment.