async void CreateScene()
{
Input.SubscribeToTouchEnd(OnTouched);
//want add image view in UrhoSharp Surface for rotatable and 3D image
var imageview = new Xamarin.Forms.Image { Source = "icon.", HeightRequest = 150, WidthRequest = 150 };
scene = new Scene();
octree = scene.CreateComponent<Octree>();
plotNode = scene.CreateChild();
var baseNode = plotNode.CreateChild().CreateChild();
var plane = baseNode.CreateComponent<StaticModel>();
plane.Model = CoreAssets.Models.Plane;
var cameraNode = scene.CreateChild();
camera = cameraNode.CreateComponent<Camera>();
cameraNode.Position = new Vector3(10, 15, 10) / 1.75f;
cameraNode.Rotation = new Quaternion(-0.121f, 0.878f, -0.305f, -0.35f);
Node lightNode = cameraNode.CreateChild();
var light = lightNode.CreateComponent<Light>();
light.LightType = LightType.Point;
light.Range = 100;
light.Brightness = 1.3f;
int size = 3;
baseNode.Scale = new Vector3(size * 1.5f, 1, size * 1.5f);
bars = new List<Bar>(size * size);
for (var i = 0f; i < size * 1.5f; i += 1.5f)
{
for (var j = 0f; j < size * 1.5f; j += 1.5f)
{
var boxNode = plotNode.CreateChild();
boxNode.Position = new Vector3(size / 2f - i, 0, size / 2f - j);
var box = new Bar(new Color(RandomHelper.NextRandom(), RandomHelper.NextRandom(), RandomHelper.NextRandom(), 0.9f));
boxNode.AddComponent(box);
box.SetValueWithAnimation((Math.Abs(i) + Math.Abs(j) + 1) / 2f);
bars.Add(box);
}
}
SelectedBar = bars.First();
SelectedBar.Select();
try
{
await plotNode.RunActionsAsync(new EaseBackOut(new RotateBy(2f, 0, 360, 0)));
}
catch (OperationCanceledException) { }
movementsEnabled = true;
}
I want to practice pixel manipulation with matrix for extract an image from another.
This is what I have done with css transformation matrix :
https://www.noelshack.com/2017-18-1493893008-capture-2.png
With the Left image 'L' I have place 4 points around the image and in the right image 'R' I find the content of the transformation.
For that i use the property transform of the css but i want to do the manipulation manually.
CSS version :
matrix3d(1.5456325781948308,1.6561987730956724,0,0.0012239101773909712,-0.4663849104791486,2.218793881308064,0,0.0009095626603861196,0,0,1,0,12.247969030166722,-17.754955132517754,0,0.9951722722714726)
Matrix 'M':
[[1.5456325781948308, 1.6561987730956724, 0, 0.0012239101773909712],
[-0.4663849104791486, 2.218793881308064, 0, 0.0009095626603861196],
[0, 0, 1, 0],
[12.247969030166722, -17.754955132517754, 0, 0.9951722722714726]]
I want to know for each pixel in the image R what are their pixel related position in the image L.
For example (0,0) in R is (52,203) in R.
For that i do this calculation.
M * P = P'
P is the pixel position in R image
P' is the pixel position in L image
P matrix is define like that:
[[x],
[y],
[0],
[1]]
So for the 0,0 position, I do this :
[[1.5456325781948308, 1.6561987730956724, 0, 0.0012239101773909712],
[-0.4663849104791486, 2.218793881308064, 0, 0.0009095626603861196],
[0, 0, 1, 0],
[12.247969030166722, -17.754955132517754, 0, 0.9951722722714726]]
X
[[0],
[0],
[0],
[1]]
=
[[0.0012239101773909712],
[0.0009095626603861196],
[0],
[0.9951722722714726]]
This is the result, but the 2 first component :
(0.0012239101773909712, 0.0009095626603861196)
is too smaller than expected. can you help me to find the problem.
scincerly,
MatrixCuriosity.
These are homogeneous coordinates. So given some [x1, y1, z1, 1] as input you obtain some [x2, y2, z2, w2] but the actual position they describe is [x2/w2, y2/w2, z2/w2], i.e. you have to divide by the last coordinate.
But this doesn't lead to the result you expected. Nor does replacing the matrix with its adjunct (or equivalently inverse), nor its transpose. Both of these are conventions that are easy to get wrong, so without spending too much thought about which version you actually have and should have, trying all four alternatives (with and without adjunct, with and without transpose) solves a huge number of trivial problems.
But not yours. So my next best bet would be that the coordinates you expect are measured from some corner of the image, while the CSS property transform-origin is at it's initial value of 50% 50% 0 so the origin of the coordinate system is in fact in the center of the object.
Actually sharing the HTML and CSS for this might have allowed me to verify this assumption. Now you have to check whether this applies to you. I remember that when I last created a projective image transformation demo to answer a question about finding the transform, I deliberately set transform-origin: 0 0; (and the various vendor-prefixed versions of this) to avoid such problems.
Thanks a lot MvG.
I follow your link and I find what I want [https://math.stackexchange.com/a/339033]
Just one thing, I have to invert the C matrix to find the pixel related L<-R
I share my code for give an idea of what you have to do
You can find my implementation in the function computeMat()
<style>
body {
touch-action: none;
overflow-y: hidden;
}
#canvas_toeic
{
position:absolute;
top:0;
left:0;
}
</style>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/mathjs/3.12.2/math.min.js"></script>
</head>
<body>
<canvas id="canvas_toeic" width="600" height="400">
</canvas>
<script type="text/javascript">
var image = new Image();
image.src = 'image.jpg';
image.onload = function() {
var c = document.getElementById("canvas_toeic");
var ratio = image.width / image.height;
var canvasWidth = document.body.clientWidth;
var canvasHeight = canvasWidth / ratio;
if(document.body.clientHeight < canvasHeight)
{
canvasHeight = document.body.clientHeight;
canvasWidth = canvasHeight * ratio;
}
var canvasLargeur = canvasWidth;
var canvasLongueur = canvasHeight;
if(canvasLargeur < canvasHeight) {
canvasLargeur = canvasHeight;
canvasLongueur = canvasWidth;
}
var canvasPixelRatio = canvasLargeur / image.width;
c.setAttribute("width", canvasWidth);
c.setAttribute("height", canvasHeight);
var ctx = c.getContext("2d");
var idPoint = -1;
var points = [];
for(var i = 0; i < 4; i++)
points[i] = {x:0, y:0};
var marginImage = Math.round(40 * canvasPixelRatio);
points[0].x = marginImage;
points[0].y = marginImage;
points[1].x = marginImage;
points[1].y = canvasHeight - marginImage;
points[2].x = canvasWidth - marginImage;
points[2].y = canvasHeight - marginImage;
points[3].x = canvasWidth - marginImage;
points[3].y = marginImage;
function draw(points) {
console.log("draw");
// Fond
ctx.fillStyle = "#222";
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
ctx.drawImage(image, marginImage, marginImage, canvasWidth - marginImage * 2, canvasHeight - marginImage * 2); // this fait référence à l'objet courant (=image)
if(idPoint == -1)
ctx.lineWidth = 3 * canvasPixelRatio;
else
ctx.lineWidth = 5 * canvasPixelRatio;
ctx.beginPath(); // Début du chemin
ctx.lineJoin = "round";
ctx.lineCap = "round";
ctx.strokeStyle = "rgba(64, 128, 255, 0.5)";
ctx.moveTo(points[0].x, points[0].y); // Le tracé part du point 50,50
for(var i = 0; i < 4; i++)
ctx.lineTo(points[i].x, points[i].y); // Un segment est ajouté vers 200,200
ctx.closePath(); // Fermeture du chemin (facultative)
ctx.stroke();
for(var i = 0; i < 4; i++)
{
var radius = 30 * canvasPixelRatio;
if(idPoint == i)
radius = 60 * canvasPixelRatio;
ctx.beginPath();
ctx.arc(points[i].x, points[i].y, radius, 0, Math.PI*2, true);
ctx.strokeStyle = "#FF8800";
ctx.fillStyle = "rgba(255, 128, 0, 0.5)";
ctx.fill();
ctx.stroke();
}
if(idPoint != -1)
{
var zoomWidth = canvasWidth / 3;
var zoomHeight = canvasHeight / 3;
var zoomMargin = 5;
var zoomAroundWidth = 50;
var zoomAroundHeight = zoomAroundWidth / ratio;
var positionMouse = points[idPoint];
var imagePositionX = (positionMouse.x - marginImage) / (canvasWidth - marginImage * 2) * image.width;
var imagePositionY = (positionMouse.y - marginImage) / (canvasHeight - marginImage * 2) * image.height;
var zoomX = 0;
var zoomY = 0;
if(imagePositionX < image.width / 2)
zoomX = canvasWidth - zoomWidth;
if(imagePositionY < image.height / 2)
zoomY = canvasHeight - zoomHeight;
ctx.fillStyle = "#F08";
ctx.fillRect(zoomX, zoomY, zoomWidth, zoomHeight);
ctx.drawImage(image, imagePositionX - zoomAroundWidth, imagePositionY - zoomAroundHeight, zoomAroundWidth * 2, zoomAroundHeight * 2, zoomX + zoomMargin, zoomY + zoomMargin, zoomWidth - zoomMargin * 2, zoomHeight - zoomMargin * 2);
ctx.lineWidth = 3 * canvasPixelRatio;
ctx.beginPath();
ctx.lineJoin = "round";
ctx.lineCap = "round";
ctx.strokeStyle = "rgba(255, 0, 0, 0.5)";
ctx.moveTo(zoomX, zoomY + zoomHeight / 2);
ctx.lineTo(zoomX + zoomWidth, zoomY + zoomHeight / 2);
ctx.moveTo(zoomX + zoomWidth / 2, zoomY);
ctx.lineTo(zoomX + zoomWidth / 2, zoomY + zoomHeight);
ctx.closePath();
ctx.stroke();
}
}
function nearPoint(points, x, y)
{
var radiusDetection = 60 * canvasPixelRatio;
var distances = [];
for(i = 0; i < 4; i++) {
var mx = x - points[i].x;
var my = y - points[i].y;
distances[i] = Math.sqrt(mx * mx + my * my);
}
minI = 0;
minD = distances[0];
for(i = 1; i < 4; i++)
{
if(minD > distances[i])
{
minD = distances[i];
minI = i;
}
}
if(minD <= radiusDetection)
return minI;
return -1;
}
function getTouchPosition(e)
{
var target = null;
var mouse = null;
if(e.changedTouches != undefined)
{
var touches = e.changedTouches;
mouse = touches[0];
target = touches[0].target;
}
else if(e.originalTarget != undefined)
{
mouse = e;
target = e.originalTarget;
}
var coordX = 0;
var coordY = 0;
if(mouse.layerX != undefined)
{
coordX = mouse.layerX;
coordY = mouse.layerY;
}
else
{
coordX = mouse.pageX;
coordY = mouse.pageY;
}
var x = coordX - target.offsetLeft;
var y = coordY - target.offsetTop;
if(x < 0) x = 0;
if(y < 0) y = 0;
if(x >= canvasWidth) x = canvasWidth - 1;
if(y >= canvasHeight) y = canvasHeight - 1;
return {'x':x, 'y':y};
}
function mouseDown(e)
{
var position = getTouchPosition(e);
idPoint = nearPoint(points, position.x, position.y);
if(idPoint == -1)
{
if(position.x < marginImage * 3 && position.y < marginImage * 3)
{
computeMat();
}
}
}
function mouseUp(e)
{
if(idPoint != -1)
{
idPoint = -1;
draw(points);
}
}
function mouseMove(e)
{
if(idPoint != -1)
{
var position = getTouchPosition(e);
points[idPoint].x = position.x;
points[idPoint].y = position.y;
draw(points);
}
}
function cancelDefault(e)
{
e.preventDefault();
}
function matStep12(pts)
{
var matP = [
[pts[0].x, pts[1].x, pts[2].x],
[pts[0].y, pts[1].y, pts[2].y],
[1, 1, 1]
];
var vecP = [[pts[3].x], [pts[3].y], [1]];
var matPi = math.inv(matP);
var vecPi = math.multiply(matPi, vecP);
var result = [
[pts[0].x * vecPi[0][0], pts[1].x * vecPi[1][0], pts[2].x * vecPi[2][0]],
[pts[0].y * vecPi[0][0], pts[1].y * vecPi[1][0], pts[2].y * vecPi[2][0]],
[vecPi[0][0], vecPi[1][0], vecPi[2][0]]
];
return result;
}
function distance(a, b)
{
var mx = b.x - a.x;
var my = b.y - a.y;
return Math.sqrt(mx * mx + my * my);
}
function computeMat()
{
var pts = getPointRelativePosition();
var widthT = distance(pts[0], pts[3]);
var widthB = distance(pts[1], pts[2]);
var heightL = distance(pts[0], pts[1]);
var heightR = distance(pts[2], pts[3]);
var maxWidth = (widthT > widthB) ? widthT : widthB;
var maxHeight = (heightL > heightR) ? heightL : heightR;
var imgWidth = Math.round(maxWidth);
var imgHeight = Math.round(maxHeight);
var matA = matStep12(pts);
var matB = matStep12([{x:0,y:0}, {x:0,y:maxHeight}, {x:maxWidth,y:maxHeight}, {x:maxWidth,y:0}]);
var matC = math.multiply(matB, math.inv(matA));
var matCi = math.inv(matC);
console.log('width:' + imgWidth + ', height:' + imgHeight);
printMat(matC);
// construct image with transformation matrice
imageData = ctx.createImageData(imgWidth, imgHeight);
var tempCanvas = document.createElement('canvas');
var tempCtx = tempCanvas.getContext('2d');
tempCanvas.width = image.width;
tempCanvas.height = image.height;
tempCtx.drawImage(image, 0, 0, image.width, image.height);
var imageDataSrc = tempCtx.getImageData(0, 0, image.width, image.height);
var mz = [matCi[0][2], matCi[1][2], matCi[2][2]];
for(var y = 0; y < imgHeight; y++)
{
var my = [matCi[0][1] * y, matCi[1][1] * y, matCi[2][1] * y];
var offsetY = y * imgWidth;
for(var x = 0; x < imgWidth; x++)
{
var mx = [matCi[0][0] * x, matCi[1][0] * x, matCi[2][0] * x];
var cx = mx[0] + my[0] + mz[0];
var cy = mx[1] + my[1] + mz[1];
var cz = mx[2] + my[2] + mz[2];
var px = Math.round(cx / cz);
var py = Math.round(cy / cz);
if(px < 0.0 || py < 0.0 || px >= image.width || py >= image.height)
{
imageData.data[pixelIndex] = 0;
imageData.data[pixelIndex + 1] = 255;
imageData.data[pixelIndex + 2] = 0;
imageData.data[pixelIndex + 3] = 255;
}
else
{
var pixelIndex = (offsetY + x) * 4;
var pixelIndexSrc = (py * image.width + px) * 4;
imageData.data[pixelIndex] = imageDataSrc.data[pixelIndexSrc];
imageData.data[pixelIndex + 1] = imageDataSrc.data[pixelIndexSrc + 1];
imageData.data[pixelIndex + 2] = imageDataSrc.data[pixelIndexSrc + 2];
imageData.data[pixelIndex + 3] = 255;
}
}
}
// here to do, image analysis
}
function getPointRelativePosition()
{
var pointOrigin = [];
for(i = 0; i < 4; i++)
{
pointOrigin[i] = {x:(points[i].x - marginImage) * image.width / (canvasWidth - marginImage * 2), y:(points[i].y - marginImage) * image.height / (canvasHeight - marginImage * 2)};
}
return pointOrigin;
}
function getPointPosition()
{
var pointOrigin = [];
for(i = 0; i < 4; i++)
{
pointOrigin[i] = {x:(points[i].x - marginImage) / (canvasWidth - marginImage * 2), y:(points[i].y - marginImage) / (canvasHeight - marginImage * 2)};
}
return pointOrigin;
}
function printPoint(pts)
{
var result = '';
for(var i = 0; i < 4; i++)
{
result += "{x:" + pts[i].x + ", y:" + pts[i].y + "},\n";
}
console.log(result);
}
function printMat(mat)
{
var result = '';
for(var i = 0; i < mat.length; i++)
{
result += "[";
for(var j = 0; j < mat[i].length; j++)
{
result += mat[i][j] + ", ";
}
result += "],\n";
}
console.log(result);
}
function canvasResize()
{
if(canvasWidth != document.body.clientWidth && canvasHeight != document.body.clientHeight)
{
var transformPoint = getPointPosition();
ratio = image.width / image.height;
canvasWidth = document.body.clientWidth;
canvasHeight = canvasWidth / ratio;
if(document.body.clientHeight < canvasHeight)
{
canvasHeight = document.body.clientHeight;
canvasWidth = canvasHeight * ratio;
}
canvasLargeur = canvasWidth;
canvasLongueur = canvasHeight;
if(canvasLargeur < canvasHeight) {
canvasLargeur = canvasHeight;
canvasLongueur = canvasWidth;
}
canvasPixelRatio = canvasLargeur / image.width;
c.setAttribute("width", canvasWidth);
c.setAttribute("height", canvasHeight);
marginImage = Math.round(40 * canvasPixelRatio);
for(i = 0; i < 4; i++)
{
points[i].x = transformPoint[i].x * (canvasWidth - marginImage * 2) + marginImage;
points[i].y = transformPoint[i].y * (canvasHeight - marginImage * 2) + marginImage;
}
draw(points);
}
}
c.addEventListener("mousedown", mouseDown, false);
c.addEventListener("mouseup", mouseUp, false);
c.addEventListener("mousemove", mouseMove, false);
c.addEventListener("touchstart", mouseDown, false);
c.addEventListener("touchend", mouseUp, false);
c.addEventListener("touchmove", mouseMove, false);
document.addEventListener("touchstart", cancelDefault, true);
document.addEventListener("touchend", cancelDefault, true);
document.addEventListener("touchmove", cancelDefault, true);
setInterval(canvasResize, 30);
draw(points);
};
</script>
So I'm trying to have the down arrow make the background of my canvas change. I'm having trouble just getting the button press to work itself.
Also I was told that I would have to have a function redraw all the shapes that are already there at the beginning as well, which I am also stuck on what to change.
Here is a JSFiddle of what I have going so far, any suggestions are appreciated!
https://jsfiddle.net/u8avnky2/
var mainCanvas = document.getElementById("canvas");
var mainContext = mainCanvas.getContext('2d');
//rotate canvas
function buttonClick() {
mainContext.rotate(20*Math.PI/180);
}
//key down event
window.addEventListener('keydown', function(event) {
if (event.keyCode === 40) {
fillBackgroundColor();
}
});
function fillBackgroundColor() {
var colors = ["red", "green", "blue", "orange", "purple", "yellow"];
var color = colors[Math.floor(Math.random()*colors.length)];
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
mainContext.fillStyle = color;
mainContext.fillRect(0, 0, canvas.width, canvas.height);
}
function check() {
mainContext.clearRect(square.x,square.y,square.w,square.h);
}
var circles = new Array();
var requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;
function Circle(radius, speed, width, xPos, yPos) {
this.radius = radius;
this.speed = speed;
this.width = width;
this.xPos = xPos;
this.yPos = yPos;
this.opacity = .1 + Math.random() * .5;
this.counter = 0;
var signHelper = Math.floor(Math.random() * 2);
if (signHelper == 1) {
this.sign = -1;
} else {
this.sign = 1;
}
}
//drawing circle
Circle.prototype.update = function () {
this.counter += this.sign * this.speed;
mainContext.beginPath();
mainContext.arc(this.xPos + Math.cos(this.counter / 100) * this.radius,
this.yPos + Math.sin(this.counter / 100) * this.radius,
this.width,
0,
Math.PI * 2,
false);
mainContext.closePath();
mainContext.fillStyle = 'rgba(255, 255, 51,' + this.opacity + ')';
mainContext.fill();
};
function setupCircles() {
for (var i = 0; i < 25; i++) {
var randomX = Math.round(-200 + Math.random() * 700);
var randomY = Math.round(-200 + Math.random() * 700);
var speed = .2 + Math.random() * 3;
var size = 5 + Math.random() * 100;
var radius = 5 + Math.random() * 100;
var circle = new Circle(radius, speed, size, randomX, randomY);
circles.push(circle);
}
drawAndUpdate();
}
setupCircles();
function drawAndUpdate() {
mainContext.clearRect(0, 0, 1000, 1000);
for (var i = 0; i < circles.length; i++) {
var myCircle = circles[i];
myCircle.update();
}
requestAnimationFrame(drawAndUpdate);
}
jsFiddle : https://jsfiddle.net/CanvasCode/u8avnky2/1/
I added a variable known as color globally, so the fillBackgroundColor can access that instead.
var color = "white";
Then in your drawAndUpdate function we just do a fillRect with the color variable using the canvas width and height and it works.
function drawAndUpdate() {
mainContext.fillStyle = color;
mainContext.fillRect(0, 0, mainCanvas.width, mainCanvas.height);
for (var i = 0; i < circles.length; i++) {
var myCircle = circles[i];
myCircle.update();
}
requestAnimationFrame(drawAndUpdate);
}
I have this little test script which I'll try to include below. It works fine in Chrome but not in IE10. IE10 gives me a nice white screen. I tried putting in the meta-equiv thing to help IE10 get the hint, but that did not change anything (in either browser). Please help.
<!-- language: lang-js -->
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="three.min.js"></script>
<script defer="defer">
// http://www.aerotwist.com/tutorials/getting-started-with-three-js/
var cubes = [];
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// camera
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 5000);
camera.position.z = 800;
// scene
var scene = new THREE.Scene();
// material
var phongMaterial = new THREE.MeshPhongMaterial({ambient: 0x555555,
color: 0x555555,
specular: 0xffffff,
shininess: 50,
side: THREE.FrontSide,
shading: THREE.SmoothShading});
var phongBack = new THREE.MeshPhongMaterial({ambient: 0x555555,
color: 0x995555,
specular: 0xffffff,
shininess: 50,
side: THREE.BackSide,
shading: THREE.SmoothShading});
var materials = [phongMaterial, phongBack];
// cube
//var cube = new THREE.Mesh(new THREE.CubeGeometry(200, 200, 200), material);
var geom = new THREE.Geometry();
var a = 100;
var b = 100;
var c = 300;
var geom = new THREE.Geometry();
var halfPi = (Math.PI / 2.0);
var u = -halfPi;
var uInc = Math.PI / 200.0;
var v = - Math.PI;
var vInc = uInc * 2.0;
var vertexNdx = 0;
var vs = [];
var on = true;
while (u < halfPi) {
var oneLine = [];
vs.push(oneLine);
while (v < Math.PI) {
var x = a * Math.cos(u) * Math.cos(v);
var y = b * Math.cos(u) * Math.sin(v);
var z = c * Math.sin(v) * Math.sin(u);
x += Math.random();
y += Math.random();
z += Math.random();
var v1 = new THREE.Vector3(x, y, z);
geom.vertices.push(v1);
oneLine.push(vertexNdx++);
if (on)
{
if (vs.length > 1 && oneLine.length > 1)
{
var uNdx = vs.length - 1;
var vNdx = oneLine.length - 1;
geom.faces.push(new THREE.Face3(vs[uNdx - 1][vNdx - 1],
vs[uNdx - 1][vNdx],
vs[uNdx][vNdx - 1]));
geom.faces.push(new THREE.Face3(vs[uNdx][vNdx - 1],
vs[uNdx - 1][vNdx],
vs[uNdx][vNdx]));
}
//on = false;
}
else
{
on = true;
}
v += vInc;
}
v = -Math.PI;
u += uInc;
}
var oneLine = vs[0];
var uNdx = vs.length - 1;
for (var vNdx = 1; vNdx < oneLine.length; vNdx++)
{
geom.faces.push(new THREE.Face3(vs[0][vNdx - 1],
vs[0][vNdx],
vs[uNdx][vNdx - 1]));
geom.faces.push(new THREE.Face3(vs[uNdx][vNdx - 1],
vs[0][vNdx],
vs[uNdx][vNdx]));
}
geom.computeFaceNormals();
var cube = new THREE.SceneUtils.createMultiMaterialObject(geom, materials);
cube.overdraw = true;
cube.rotation.x = Math.PI * 0.1;
scene.add(cube);
cubes.push(cube);
var geom = new THREE.Geometry();
var a = 100;
var b = 100;
var c = 300;
var geom = new THREE.Geometry();
var halfPi = (Math.PI / 2.0);
var u = -halfPi;
var uInc = Math.PI / 200.0;
var v = - Math.PI;
var vInc = uInc * 2.0;
var vertexNdx = 0;
var vs = [];
var on = true;
while (u < halfPi) {
var oneLine = [];
vs.push(oneLine);
var xRand = Math.random();
while (v < Math.PI) {
var x = a * Math.cos(u) * Math.cos(v);
var y = b * Math.cos(u) * Math.sin(v);
var z = c * Math.sin(v) * Math.sin(u);
x += xRand;
y += Math.random();
z += Math.random();
var v1 = new THREE.Vector3(x, y, z);
geom.vertices.push(v1);
oneLine.push(vertexNdx++);
if (on)
{
if (vs.length > 1 && oneLine.length > 1)
{
var uNdx = vs.length - 1;
var vNdx = oneLine.length - 1;
geom.faces.push(new THREE.Face3(vs[uNdx - 1][vNdx - 1],
vs[uNdx - 1][vNdx],
vs[uNdx][vNdx - 1]));
geom.faces.push(new THREE.Face3(vs[uNdx][vNdx - 1],
vs[uNdx - 1][vNdx],
vs[uNdx][vNdx]));
}
//on = false;
}
else
{
on = true;
}
v += vInc;
}
v = -Math.PI;
u += uInc;
}
var oneLine = vs[0];
var uNdx = vs.length - 1;
for (var vNdx = 1; vNdx < oneLine.length; vNdx++)
{
geom.faces.push(new THREE.Face3(vs[0][vNdx - 1],
vs[0][vNdx],
vs[uNdx][vNdx - 1]));
geom.faces.push(new THREE.Face3(vs[uNdx][vNdx - 1],
vs[0][vNdx],
vs[uNdx][vNdx]));
}
geom.applyMatrix(new THREE.Matrix4().translate(new THREE.Vector3(200, 0, 0)));
geom.computeFaceNormals();
var cube = new THREE.SceneUtils.createMultiMaterialObject(geom, materials);
cube.overdraw = true;
cube.rotation.x = Math.PI * 0.1;
scene.add(cube);
cubes.push(cube);
var geom = new THREE.Geometry();
var a = 100;
var b = 100;
var c = 300;
var geom = new THREE.Geometry();
var halfPi = (Math.PI / 2.0);
var u = -halfPi;
var uInc = Math.PI / 200.0;
var v = - Math.PI;
var vInc = uInc * 2.0;
var vertexNdx = 0;
var vs = [];
var on = true;
while (u < halfPi) {
var oneLine = [];
vs.push(oneLine);
var yRand = Math.random();
while (v < Math.PI) {
var x = a * Math.cos(u) * Math.cos(v);
var y = b * Math.cos(u) * Math.sin(v);
var z = c * Math.sin(v) * Math.sin(u);
x += Math.random();
y += yRand;
z += Math.random();
var v1 = new THREE.Vector3(x, y, z);
geom.vertices.push(v1);
oneLine.push(vertexNdx++);
if (on)
{
if (vs.length > 1 && oneLine.length > 1)
{
var uNdx = vs.length - 1;
var vNdx = oneLine.length - 1;
geom.faces.push(new THREE.Face3(vs[uNdx - 1][vNdx - 1],
vs[uNdx - 1][vNdx],
vs[uNdx][vNdx - 1]));
geom.faces.push(new THREE.Face3(vs[uNdx][vNdx - 1],
vs[uNdx - 1][vNdx],
vs[uNdx][vNdx]));
}
//on = false;
}
else
{
on = true;
}
v += vInc;
}
v = -Math.PI;
u += uInc;
}
var oneLine = vs[0];
var uNdx = vs.length - 1;
for (var vNdx = 1; vNdx < oneLine.length; vNdx++)
{
geom.faces.push(new THREE.Face3(vs[0][vNdx - 1],
vs[0][vNdx],
vs[uNdx][vNdx - 1]));
geom.faces.push(new THREE.Face3(vs[uNdx][vNdx - 1],
vs[0][vNdx],
vs[uNdx][vNdx]));
}
geom.applyMatrix(new THREE.Matrix4().translate(new THREE.Vector3(-200, 0, 0)));
geom.computeFaceNormals();
var cube = new THREE.SceneUtils.createMultiMaterialObject(geom, materials);
cube.overdraw = true;
cube.rotation.x = Math.PI * 0.1;
scene.add(cube);
cubes.push(cube);
// add subtle ambient lighting
var ambientLight = new THREE.AmbientLight(0xdddddd);
scene.add(ambientLight);
// directional lighting
var directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(1, 1, 1).normalize();
scene.add(directionalLight);
var screenW = window.innerWidth;
var screenH = window.innerHeight;
var spdx = 0, spdy = 0, mouseX = 0, mouseY = 0, mouseDown = false;
document.addEventListener('mousemove', function(event) {
mouseX = event.clientX;
mouseY = event.clientY;
}, false);
document.body.addEventListener('mousedown', function(event) {
mouseDown = true;
}, false);
document.body.addEventListener('mouseup', function(event) {
mouseDown = false;
}, false);
function animate() {
spdy = (screenH / 2 - mouseY) / 40;
spdx = (screenW / 2 - mouseX) / 40;
if (mouseDown) {
for (var loop = 0; loop < cubes.length; loop++) {
var cube = cubes[loop];
cube.rotation.x = spdy;
cube.rotation.y = spdx;
}
}
renderer.render(scene, camera);
requestAnimationFrame(function(){
animate();
});
};
// start animation
animate();
</script>
</body>
</html>
And feel free to steal my little play test code if you like it. If you make something that looks cool, let me see it! I'm looking for organic-looking shapes that are made mathematically.
IE10 does not support WebGL. I think your code will work if you just switch from WebGLRenderer to CanvasRenderer, but the lighting won't be as accurate.
Hi I founded a flash as3 carousel by searching in internet. The code is:
var centerX:Number = stage.stageWidth / 1.7;
var centerY:Number = stage.stageHeight / 2;
var radiusX:Number = 180;
var radiusY:Number = 50;
var speed:Number = 0.1;
var minSpeed:Number = -0.05;
var maxSpeed:Number = 0.05;
var rangeSpeed:Number = maxSpeed - minSpeed;
var minY:Number = centerY - radiusY;
var maxY:Number = centerY + radiusY;
var rangeY:Number = maxY - minY;
var minScale:Number = 0.2;
var maxScale:Number = 1.0;
var rangeScale:Number = maxScale - minScale;
var itemArray:Array = new Array();
itemArray.push(new cubeblue());
itemArray.push(new cubeblue());
itemArray.push(new cubeblue());
itemArray.push(new cubeblue());
itemArray.push(new cubeblue());
itemArray.push(new cubeblue());
var canvas:MovieClip = new MovieClip();
addChild(canvas);
for (var i:Number = 0; i < itemArray.length; i++)
{
canvas.addChild(itemArray[i]);
itemArray[i].buttonMode = true;
itemArray[i].addEventListener(MouseEvent.MOUSE_DOWN, stop);
itemArray[i].itemAngle = Math.PI * 2 / itemArray.length * i;
itemArray[i].addEventListener(Event.ENTER_FRAME, animate);
}
function animate(e:Event):void
{
speed = mouseX / stage.stageWidth * rangeSpeed + minSpeed;
e.currentTarget.x = Math.cos(e.currentTarget.itemAngle) * radiusX + centerX;
e.currentTarget.y = Math.sin(e.currentTarget.itemAngle) * radiusY + centerY;
e.currentTarget.itemAngle += speed;
itemArray.sortOn("y");
for(var i:Number = 0; i < itemArray.length; i++)
{
canvas.setChildIndex(itemArray[i], i);
var pct:Number = (itemArray[i].y - minY) / rangeY;
var scale:Number = pct * rangeScale + minScale;
itemArray[i].scaleX = itemArray[i].scaleY = scale;
}
}
function stop(event:MouseEvent):void {
}
Now, after some modification, with the function stop I want to stop the carousel by clicking on one element on the layer, but I don't know how I can do this! Someone can help me?
Regards`
First of all, you can't name a function stop unless you plan to override it, which in this case you aren't. To stop the carousel from spinning you simply need to remove the ENTER_FRAME event. I renamed your stop function to stopAnimate
var centerX:Number = stage.stageWidth / 1.7;
var centerY:Number = stage.stageHeight / 2;
var radiusX:Number = 180;
var radiusY:Number = 50;
var speed:Number = 0.1;
var minSpeed:Number = -0.05;
var maxSpeed:Number = 0.05;
var rangeSpeed:Number = maxSpeed - minSpeed;
var minY:Number = centerY - radiusY;
var maxY:Number = centerY + radiusY;
var rangeY:Number = maxY - minY;
var minScale:Number = 0.2;
var maxScale:Number = 1.0;
var rangeScale:Number = maxScale - minScale;
var itemArray:Array = new Array();
itemArray.push(new cubeblue());
itemArray.push(new cubeblue());
itemArray.push(new cubeblue());
itemArray.push(new cubeblue());
itemArray.push(new cubeblue());
itemArray.push(new cubeblue());
var canvas:MovieClip = new MovieClip();
addChild(canvas);
for (var i:Number = 0; i < itemArray.length; i++)
{
canvas.addChild(itemArray[i]);
itemArray[i].buttonMode = true;
itemArray[i].addEventListener(MouseEvent.CLICK, stopAnimate);
itemArray[i].itemAngle = Math.PI * 2 / itemArray.length * i;
itemArray[i].addEventListener(Event.ENTER_FRAME, animate);
}
function animate(e:Event):void
{
speed = mouseX / stage.stageWidth * rangeSpeed + minSpeed;
e.currentTarget.x = Math.cos(e.currentTarget.itemAngle) * radiusX + centerX;
e.currentTarget.y = Math.sin(e.currentTarget.itemAngle) * radiusY + centerY;
e.currentTarget.itemAngle += speed;
itemArray.sortOn("y");
for(var i:Number = 0; i < itemArray.length; i++)
{
canvas.setChildIndex(itemArray[i], i);
var pct:Number = (itemArray[i].y - minY) / rangeY;
var scale:Number = pct * rangeScale + minScale;
itemArray[i].scaleX = itemArray[i].scaleY = scale;
}
}
function stopAnimate(event:MouseEvent):void
{
for (var i:Number = 0; i < itemArray.length; i++)
{
itemArray[i].removeEventListener(Event.ENTER_FRAME, animate);
}
}
now to renable the animation, you can simply add a click event to lets say a button and that function will perform
for (var i:Number = 0; i < itemArray.length; i++)
{
itemArray[i].addEventListener(Event.ENTER_FRAME, animate);
}
which will just add the ENTER_FRAME event back on the movie clips in itemArray