Last active
July 22, 2016 00:52
-
-
Save fabiancook/6597cbb2a6aa65701327466aff6fabba to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function corrugatedVectors(options) { | |
const length = lengthToPixel(options.length), | |
troughLength = lengthToPixel(options.troughLength), | |
ridgeLength = lengthToPixel(options.ridgeLength), | |
ridgeHeight = lengthToPixel(options.ridgeHeight), | |
offsetY = lengthToPixel(options.offsetY), | |
offsetX = lengthToPixel(options.offsetX), | |
offsetZ = lengthToPixel(options.offsetZ), | |
ridgeAngle = options.ridgeAngle, | |
angle = options.angle, | |
ridgeAngleLength = calculateAngledWith(ridgeHeight, ridgeAngle), | |
groupLength = troughLength + ridgeLength + ridgeAngleLength, | |
totalGroups = Math.floor(length / groupLength), | |
totalPoints = totalGroups * 4 | |
// Start in negative direction | |
var currentLength = -(isTroughOrRidge(0) ? troughLength : ridgeLength); | |
return Array.from({ | |
length: totalPoints | |
}, function(_, index) { | |
if (currentLength >= length) { | |
return false; | |
} | |
const trough = isTroughOrRidge(index), | |
previousTrough = isTroughOrRidge(index - 1); | |
const thisLength = lengthForIndex(index, troughLength, ridgeLength, ridgeAngleLength), | |
nextLength = lengthForIndex(index + 1, troughLength, ridgeLength, ridgeAngleLength), | |
nextNextLength = lengthForIndex(index + 2, troughLength, ridgeLength, ridgeAngleLength); | |
if ( | |
(currentLength + thisLength) >= length || | |
(trough && previousTrough && (currentLength + thisLength + nextLength) >= length) || | |
(trough && previousTrough && (currentLength + thisLength + nextLength + nextNextLength) >= length) | |
) { | |
currentLength = length; | |
} else { | |
currentLength += thisLength; | |
} | |
const height = trough || (!trough && currentLength === length && trough !== previousTrough) ? 0 : ridgeHeight; | |
var vector = new THREE.Vector3(currentLength, 0, height); | |
vector = changeByAngle(vector, angle); | |
vector = offsetXYZ(vector, offsetX, offsetY, offsetZ); | |
return vector; | |
}) | |
.filter(function(vector) { | |
return !!vector; | |
}); | |
} | |
function offsetXYZ(vector, x, y, z) { | |
return vector.clone().add( | |
new THREE.Vector3(x || 0, y || 0, z || 0) | |
) | |
} | |
function changeByAngle(vector, angle) { | |
if (!angle || angle === 0) { | |
return vector; | |
} | |
var quaternion = new THREE.Quaternion(); | |
quaternion.setFromAxisAngle(new THREE.Vector3(0, 1, 0), THREE.Math.degToRad(angle)); | |
return vector.clone().applyQuaternion(quaternion); | |
} | |
function lengthForIndex(index, troughLength, ridgeLength, ridgeAngleLength) { | |
const trough = isTroughOrRidge(index), | |
previousTrough = isTroughOrRidge(index - 1); | |
return trough !== previousTrough ? | |
ridgeAngleLength : | |
(trough ? troughLength : ridgeLength); | |
} | |
function calculateAngledWith(ridgeHeight, angle) { | |
const result = Math.tan(THREE.Math.degToRad(angle)) * ridgeHeight; | |
if (Math.abs(Math.ceil(result) - result) < 0.000000001) { | |
return Math.ceil(result); | |
} | |
if (Math.abs(Math.floor(result) - result) < 0.000000001) { | |
return Math.floor(result); | |
} | |
return result; | |
} | |
function isTroughOrRidge(index) { | |
const decimalPart = ((index + 1) / 4).toString().split('.')[1]; | |
return !((index + 1) > 1 && ((index + 1) % 4 === 0 || (decimalPart && (+decimalPart) >= 75))); | |
} | |
function lengthToPixel(length) { | |
return length * 0.5; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment