Is there a way to rotate the object with the property rotation, and then calculate its x and y coordinates as if it was turned around some point
without measurement accuracy?
public static function pointRotate (object:DisplayObject, center:Point,angle:Number) : void
{
var r:Number = angle * Math.PI / 180;
var s:Number = Math.sin(r);
var c:Number = Math.cos(r);
var dX:Number = object.x - center.x;
var dY:Number = object.y - center.y;
object.rotation += angle;
object.x = center.x + dX * c - dY * s;
object.y = center.y + dX * s + dY * c;
}
package
{
import flash.geom.Point;
import flash.display.DisplayObject;
public function pointRotate(object:DisplayObject, center:Point, angle:Number) : void
{
// return to zero
angle += object.rotation;
var a0:Number = - object.rotation * Math.PI / 180;
var s0:Number = Math.sin(a0);
var c0:Number = Math.cos(a0);
var dX0:Number = object.x - center.x;
var dY0:Number = object.y - center.y;
object.rotation = 0;
object.x = Math.round(center.x + dX0 * c0 - dY0 * s0);
object.y = Math.round(center.y + dX0 * s0 + dY0 * c0);
// new rotation
var r:Number = angle * Math.PI / 180;
var s:Number = Math.sin(r);
var c:Number = Math.cos(r);
var dX:Number = object.x - center.x;
var dY:Number = object.y - center.y;
object.rotation += angle;
object.x = center.x + dX * c - dY * s;
object.y = center.y + dX * s + dY * c;
}
}
I want to draw a cylinder on canvas with control box to re size the cylinder.
Here's some javascript code I created to answer my own question:
function drawCylinder ( x, y, w, h ) {
context.beginPath(); //to draw the top circle
for (var i = 0 * Math.PI; i < 2 * Math.PI; i += 0.001) {
xPos = (this.x + this.w / 2) - (this.w / 2 * Math.sin(i)) *
Math.sin(0 * Math.PI) + (this.w / 2 * Math.cos(i)) *
Math.cos(0 * Math.PI);
yPos = (this.y + this.h / 8) + (this.h / 8 * Math.cos(i)) *
Math.sin(0 * Math.PI) + (this.h / 8 *
Math.sin(i)) * Math.cos(0 * Math.PI);
if (i == 0) {
context.moveTo(xPos, yPos);
}
else
{
context.lineTo(xPos, yPos);
}
}
context.moveTo(this.x, this.y + this.h / 8);
context.lineTo(this.x, this.y + this.h - this.h / 8);
for (var i = 0 * Math.PI; i < Math.PI; i += 0.001) {
xPos = (this.x + this.w / 2) - (this.w / 2 * Math.sin(i)) * Math.sin(0 * Math.PI) + (this.w / 2 * Math.cos(i)) * Math.cos(0 * Math.PI);
yPos = (this.y + this.h - this.h / 8) + (this.h / 8 * Math.cos(i)) * Math.sin(0 * Math.PI) + (this.h / 8 * Math.sin(i)) * Math.cos(0 * Math.PI);
if (i == 0) {
context.moveTo(xPos, yPos);
}
else
{
context.lineTo(xPos, yPos);
}
}
context.moveTo(this.x + this.w, this.y + this.h / 8);
context.lineTo(this.x + this.w, this.y + this.h - this.h / 8);
context.stroke();
}
Thank you! This is just what I was looking for. While implementing your function in my own code I made some changes like passing in the canvas context as an argument, simplifying the math and getting the code to pass JSLint.
function drawCylinder(ctx, x, y, w, h) {
'use strict';
var i, xPos, yPos, pi = Math.PI, twoPi = 2 * pi;
ctx.beginPath();
for (i = 0; i < twoPi; i += 0.001) {
xPos = (x + w / 2) - (w / 2 * Math.cos(i));
yPos = (y + h / 8) + (h / 8 * Math.sin(i));
if (i === 0) {
ctx.moveTo(xPos, yPos);
} else {
ctx.lineTo(xPos, yPos);
}
}
ctx.moveTo(x, y + h / 8);
ctx.lineTo(x, y + h - h / 8);
for (i = 0; i < pi; i += 0.001) {
xPos = (x + w / 2) - (w / 2 * Math.cos(i));
yPos = (y + h - h / 8) + (h / 8 * Math.sin(i));
if (i === 0) {
ctx.moveTo(xPos, yPos);
} else {
ctx.lineTo(xPos, yPos);
}
}
ctx.moveTo(x + w, y + h / 8);
ctx.lineTo(x + w, y + h - h / 8);
ctx.stroke();
}
If you want to draw a 3D cylinder, the easiest way is to use a library like tQuery (http://jeromeetienne.github.com/tquery/) :
var world = tQuery.createWorld().boilerplate().start();
var object = tQuery. createCylinder().addTo(world);
If you want to draw a '2d' cylinder, you can do so using canvas 2d API to draw a rectangle then a elipse in top of it. It will appear as a cylinder.
var canvas = document.getElementById('canvas')
var ctx = canvas.getContext('2d');
var pos={};
const angleToRadian = function (angle) {
return Math.PI / 180 * angle;
}
var Arc = function (x, y, r, d,s) {
this.r = r;
this.x = x;
this.y = y;
// this.d=d;
ctx.beginPath();
ctx.arc(x, y, r, angleToRadian(0), angleToRadian(180));
ctx.moveTo((Number(x) + Number(r)), y);
// ctx.lineTo((Number(x) + Number(r)), d);
ctx.arc(x, y - d, r, angleToRadian(0), angleToRadian(360));
ctx.moveTo((Number(x)+Number(r)),y);
ctx.lineTo((Number(x)+Number(lX())), ((Number(y)-Number(d))+Number(r)-Number(lY())));
// ctx.moveTo((Number(x)+Number(lX())), ((Number(y)-Number(d))-Number(lY())+Number(r)));
ctx.lineTo((Number(x)+Number(lX())),(Number(y)+Number(r)-Number(lY())));
// ctx.moveTo((Number(x)+Number(lX())),(Number(y)+Number(r)-Number(lY())));
ctx.lineTo(Number(x), ((Number(y)+Number(r))-Number(d)));
// ctx.moveTo(Number(x), ((Number(y)+Number(r))-Number(d)));
ctx.lineTo(Number(x),(Number(y)+Number(r)));
// ctx.moveTo(Number(x),(Number(y)+Number(r)));
ctx.lineTo((Number(x)-Number(lX())), (Number(y)-Number(d)+Number(r)-Number(lY())));
// ctx.moveTo((Number(x)-Number(lX())), (Number(y)-Number(d)+Number(r)-Number(lY())));
ctx.lineTo((Number(x)-Number(lX())), (Number(y)+Number(r)-Number(lY())));
// ctx.moveTo((Number(x)-Number(lX())), (Number(y)+Number(r)-Number(lY())));
ctx.lineTo((Number(x)-Number(r)), (Number(y)-Number(d)));
// ctx.moveTo((Number(x)-Number(r)), (Number(y)-Number(d)));
ctx.lineTo((Number(x)-Number(r)), y);
ctx.strokeStyle = "#9c3028";
ctx.closePath();
// ctx.stroke();
ctx.fillStyle="#9b3028"
ctx.fill();
}
var lY = function () {
return Math.sqrt((Math.pow(((Math.cos(67.5 * Math.PI / 180) * this.r) * 2), 2) -
Math.pow((Math.cos(22.5 * Math.PI / 180) * (Math.cos(67.5 * Math.PI / 180) * this.r) * 2), 2)));
}
var lX = function () {
return Math.sqrt((Math.pow(((Math.cos(67.5 * Math.PI / 180) * this.r) * 2), 2) - (Math.pow(((Math.cos(67.5 * Math.PI / 180) * this.r) * 2), 2) -
Math.pow((Math.cos(22.5 * Math.PI / 180) * (Math.cos(67.5 * Math.PI / 180) * this.r) * 2), 2))));
}
document.addEventListener('mouseup',mouseUp);
document.addEventListener('mousedown',mouseDown);
document.addEventListener('mousemove',draw);
function mouseDown(e){
pos.x=e.clientX;
pos.y=e.clientY;
}
function mouseUp(e){
pos.pozX=e.clientX;
pos.pozY=e.clientY;
}
function draw(e){
if(e.buttons!==1) return;
ctx.clearRect(0,0,500,500);
Arc(pos.x, pos.y, e.clientY, e.clientX);
}
package {
import flash.display.Sprite;
import flash.geom.Point;
import flash.events.Event;
public class Game2 extends Sprite {
var balls:Array;
var radius:Number = 50;
var centerX:Number = stage.stageWidth / 2;
var centerY:Number = stage.stageHeight / 2;
var i:int = 0;
var angle:Number = 0.1;
var sin:Number = Math.sin(angle);
var cos:Number = Math.cos(angle);
public function Game2() {
init();
}
function init():void
{
balls = new Array();
for(i = 0; i < 8; i++)
{
var ball:Ball = new Ball(10, 0x00FF00);
var xposition = centerX + Math.cos(i / 8 * Math.PI * 2) * radius;
var yposition = centerY + Math.sin(i / 8 * Math.PI * 2) * radius;
ball.x = xposition;
ball.y = yposition;
addChild(ball);
balls.push(ball);
}
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
function onEnterFrame(e:Event):void
{
for(i = 0; i < balls.length; i++)
{
var ball:Ball = balls[i];
var x1:Number = ball.x - stage.stageWidth / 2;
var y1:Number = ball.y - stage.stageHeight / 2;
var x2:Number = cos * x1 - sin * y1;
var y2:Number = cos * y1 + sin * x1;
ball.x = stage.stageWidth / 2 + x2;
ball.y = stage.stageHeight / 2 + y2;
}
}
}
}
Can someone explain the work of this formula?:
var x2:Number = cos * x1 - sin * y1;
var y2:Number = cos * y1 + sin * x1;
i just can't figure it out, if we edit it like this:
var x2:Number = x1 - y1;
var y2:Number = x1 + y1;
all the balls are moving so fast and get out of screen bounds, and also why if we change it like this:
var x2:Number = cos * x1 - sin * y1;
var y2:Number = cos * y1 + sin * x1;
or
var x2:Number = cos * x1 - sin * y1;
var y2:Number = cos * y1 + sin * x1;
it will work equal, as far as i understanded is that here happens some kind of simetry, if we are on the left or right sides the velocity x == 0 and y is at the maximum velocity of its position the y slows down each time he get closer to the top or bottom, if we are on the top or bottom the velocity y == 0 and x is at maximum speed of his position then also slows down each time he gets closer to the right or left sides, i traced it, but i can't understand why we have to multiply it by cos and sin, i've traced this moments but still can't figure it out, can anyone explain this moment?
The two formulas represent a rotation matrix multiplied with a vector.
If I'd like to make a circle with particles, I'd define random coordinates for particles like this:
for(var i:int = 0; i != 100; i++)
{
var angle:Number = Math.random() * 360;
var r:Number = 600;
var nX:Number = r * Math.cos(angle / 180 * Math.PI);
var nY:Number = r * Math.sin(angle / 180 * Math.PI);
}
But I want to make a ball with particles on 3d space but I don't know how to define random coordinates for particles. Radius is fixed again but there should be a "nZ" value. Can you help me to define these coordinates?
for(var i:int = 0; i != 100; i++)
{
var angle:Number = Math.random() * 360;
var r:Number = 600;
var nX:Number = ???
var nY:Number = ???
var nZ:Number = ???
}
Thanks in advance...
Spherical coordinates are what you want.
You need two angles:
for(var i:int = 0; i != 100; i++)
{
var azimuthAngle:Number = Math.random() * 360;
var elevationAngle:Number = (Math.random() * 180) - 90;
var r:Number = 600;
var nX:Number =
r * Math.cos(azimuthAngle / 180 * Math.PI) * Math.sin(elevationAngle / 180 * Math.PI);
var nY:Number =
r * Math.sin(azimuthAngle / 180 * Math.PI) * Math.sin(elevationAngle / 180 * Math.PI);
var nZ:Number =
r * Math.cos(elevationAngle / 180 * Math.PI);
}
using action script how to draw a semi circle...i need to add tha semicircle in another circle the circle looks like this
![alt text][1]
how to draw a semi circle inside that circle
Use the following function to draw the required arc.
function drawArc(centerX, centerY, radius, startAngle, arcAngle, steps){
startAngle -= .25;
var twoPI = 2 * Math.PI;
var angleStep = arcAngle/steps;
var xx = centerX + Math.cos(startAngle * twoPI) * radius;
var yy = centerY + Math.sin(startAngle * twoPI) * radius;
moveTo(xx, yy);
for(var i=1; i<=steps; i++){
var angle = startAngle + i * angleStep;
xx = centerX + Math.cos(angle * twoPI) * radius;
yy = centerY + Math.sin(angle * twoPI) * radius;
lineTo(xx, yy);
}
}
lineStyle(0, 0xFF0000);
drawArc(250, 250, 200, 45/360, -90/360, 20);
Semicircle? Well its joining the end points isn't it. Use lineto.
Thank you so much loxxy.. I have made a few alteration and got dashed line too.
function drawArc(centerX, centerY, radius, startAngle, arcAngle, steps){
centerY=centerY+radius
startAngle -= .25;
var twoPI = 2 * Math.PI;
var angleStep = arcAngle/steps;
trace(angleStep)
var xx = centerX + Math.cos(startAngle * twoPI) * radius;
var yy = centerY + Math.sin(startAngle * twoPI) * radius;
mc.graphics.moveTo(xx, yy);
for(var i=1; i<=steps; i++){
var angle = startAngle + i * angleStep;
xx = centerX + Math.cos(angle * twoPI) * radius;
yy = centerY + Math.sin(angle * twoPI) * radius;
if(i%2==0){
mc.graphics.moveTo(xx, yy);
}else{
mc.graphics.lineTo(xx, yy);
}
}
}