xxxxxxxxxx
444
/**************************************************************************************************
* program to check the difference between Cartesian Coordinate and Polar Coordinate
**************************************************************************************************/
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
let origin; // origin point (p5.Vector)
let v; // position of them mouse (p5.Vector)
let span = 50; // span of drawing dotted lines
let maxLen; // length of the coordinate line
let coordIndex; // index number of which coordinate is shown.(0:Cartesian, 1:Polar)
let coordColor; // color of the lines and numbers of the coordinate (make it light gray as it may not disturb vector line)
let infoDiv; // Div element for showing vector informations
let coordDiv; // Div element for showing "select coordinate:"
let coordRadio; // RadioButton element for choosing which coordinate to show.
//-----------------------------------------------------------------------------
// setup function : done once at the beginning.
//-----------------------------------------------------------------------------
function setup() {
// Define canvas
createCanvas(800, 800);
// Default coordinate at the beginning is 0 (Cartesian Coordinate)
coordIndex = 0;
// Create vector object of the origin point
origin = createVector(width / 2, height / 2);
// Create vector object of the mouse point
v = createVector();
// Set maxLen to be the length between(0,0) and origin.
maxLen = dist(0, 0, origin.x, origin.y);
// Set color of the coordinate lines and numbers
coordColor = 160;
// Define infoDiv
infoDiv = createDiv();
infoDiv.position(width + 20, 10)
// Define coordDiv
coordDiv = createDiv();
coordDiv.position(width + 20, 250);
coordDiv.html("switch coordinate:<br>(press 's' to switch coords.)");
// Define coordRadio
coordRadio = createRadio();
coordRadio.size(200);
coordRadio.option(0, "Cartesian Coordinate")
coordRadio.option(1, "Polar Coordinate")
coordRadio.position(width + 20, 330);
// Set radio button to default coordinate
coordRadio.selected(coordIndex.toString());
}
//-----------------------------------------------------------------------------
// draw function: loops forever
//-----------------------------------------------------------------------------
function draw() {
// Set background to very bright gray
background(240);
// Set which coords are chosen
coordIndex = coordRadio.value();
// Draw coordinate plane
if (coordIndex == 1) { drawPolarCoords(); }
else if (coordIndex == 0) { drawCartCoords(); }
// Set vector v to the mouse position
v.x = mouseX;
v.y = mouseY;
// draw line from origin point to v point
stroke(0);
strokeWeight(1);
line(origin.x, origin.y, v.x, v.y);
// Show informations on the canvas according to the chosen coordinates.
//------------------------------------
// Get angle here, because angle is needed for adjusting the position of displaying informations.
let angle = p5.Vector.sub(v, origin).heading();
//*** Polar Coordinate ***//
if (coordIndex == 1) {
// Theta
// if the angle is less than 0 (upper half of the canvas)
if (angle < 0) {
// draw arc. because angle < 0, angles to pass into 'arc' is in the order of angle, 0.
stroke(0);
noFill();
arc(origin.x, origin.y, 30, 30, angle, 0);
// show the number of theta
noStroke();
fill(0);
textSize(14);
// default point is origin.x + 20, origin.y - 5, by LEFT,BOTTOM alignment.
textAlign(LEFT, BOTTOM);
let ax = origin.x + 20;
let ay = origin.y - 5;
// if the angle is larger than -0.8 (which means -0.8 < angle < 0),
// adjust the display posision as vector line and information number overlaps.
if (angle > -0.8) {
// display the information below origin.y
textAlign(LEFT, TOP);
ay = origin.y + 20;
}
// Display angle information
text("θ= " + nfc(angle, 2) + " rad (" + nfc(degrees(angle), 2) + "°)", ax, ay)
} else {
// draw arc. because angle > 0, angles to pass into 'arc' is in the order of 0, angle.
stroke(0);
noFill();
arc(origin.x, origin.y, 30, 30, 0, angle);
// show the number of theta
noStroke();
fill(0);
textSize(14);
// default point is origin.x + 20, origin.y +20 by LEFT,TOP alignment.
textAlign(LEFT, TOP);
let ax = origin.x + 20;
let ay = origin.y + 20;
// if the angle is larger than -1 (which means 0 < angle < 1),
// adjust the display posision as vector line and information number overlaps.
if (angle < 1) {
// display the information above origin.y
textAlign(LEFT, BOTTOM);
ay = origin.y - 5;
}
// Display angle information
text("θ= " + nfc(angle, 2) + " rad (" + nfc(degrees(angle), 2) + "°)", ax, ay)
}
// length
// calc length. v.mag() gives the magnitude from (0,0), so get distance between origin and v.
let len = p5.Vector.dist(v, origin);
// default point is origin.x, origin.y -10 by LEFT,BOTTOM alignment.
textAlign(LEFT, BOTTOM);
let lx = v.x;
let ly = v.y - 10;
// if the angle is between 0 and PI, display information lower right of the mouse pointer.
if (angle > 0 && angle < PI) {
lx = v.x + 20;
ly = v.y + 45;
}
// display length.
noStroke();
fill(0);
textSize(14);
text("r= " + nfc(len, 2), lx, ly);
}
//*** Cartesian Coordinate ***//
else if (coordIndex == 0) {
// default point is origin.x, origin.y -10 by LEFT,BOTTOM alignment.
textAlign(LEFT, BOTTOM);
let lx = v.x;
let ly = v.y - 10;
// if the angle is between 0 and PI, display information lower right of the mouse pointer.
if (angle > 0 && angle < PI) {
lx = v.x + 20;
ly = v.y + 20;
}
// display x,y values.
noStroke();
fill(0);
textSize(14);
text("x= " + floor(v.x - origin.x) + ", y= " + floor(v.y - origin.y), lx, ly);
}
// draw an arrow at the edge of the vector v
stroke(0);
strokeWeight(1);
push();
drawArrow(v.x, v.y);
pop();
// Display informations on the right of the canvas
infoDiv.html(getInfoMsg());
}
//-----------------------------------------------------------------------------
// drawPolarCoords function
//-----------------------------------------------------------------------------
function drawPolarCoords() {
stroke(coordColor);
strokeWeight(1);
noFill();
line(0, origin.y, width, origin.y);
line(origin.x, 0, origin.x, height);
strokeWeight(0.3);
for (let i = span; i <= maxLen; i += span) {
if (i % (span * 2) == 0) { drawingContext.setLineDash([]); }
else { drawingContext.setLineDash([5, 5]); }
circle(origin.x, origin.y, i * 2);
}
drawingContext.setLineDash([5, 5]);
strokeWeight(0.3);
for (let i = 0; i < 360; i += 30) {
if (i % 90 == 0) continue;
let a = radians(i);
let x = maxLen * cos(a) + origin.x;
let y = maxLen * sin(a) + origin.y;
line(origin.x, origin.y, x, y);
}
drawingContext.setLineDash([]);
noStroke();
fill(coordColor);
textSize(15);
textAlign(RIGHT, TOP);
text("O", origin.x - 2, origin.y + 2);
textSize(12);
for (let i = 0; i <= width; i += span) {
if (i == origin.x) continue;
let offset;
if (i < origin.x) {
textAlign(LEFT, TOP);
offset = 2;
} else {
textAlign(RIGHT, TOP);
offset = -2;
}
noStroke();
fill(coordColor);
text(i - origin.x, i + offset, origin.y + 2);
}
for (let j = 0; j <= height + 1; j += span) {
if (j == origin.y) continue;
let offset;
if (j < origin.y) {
textAlign(RIGHT, TOP);
offset = 2;
} else {
textAlign(RIGHT, BOTTOM);
offset = -2;
}
noStroke();
fill(coordColor);
text(j - origin.y, origin.x - 2, j + offset);
}
textAlign(RIGHT, BOTTOM); text("0 (0°)", width - 2, origin.y - 5);
textAlign(LEFT, BOTTOM); text("PI (180°)", 5, origin.y - 5);
textAlign(LEFT, BOTTOM); text("HALF_PI (90°)", origin.x + 5, height - 5);
textAlign(LEFT, TOP); text("-HALF_PI (-90°)", origin.x + 5, 5);
}
//-----------------------------------------------------------------------------
// drawCartCoords function
//-----------------------------------------------------------------------------
function drawCartCoords() {
stroke(coordColor);
strokeWeight(1);
noFill();
line(0, origin.y, width, origin.y);
line(origin.x, 0, origin.x, height);
for (let i = 0; i <= width; i += span) {
if (i == origin.x) continue;
if (i % (span * 2) == 0) { drawingContext.setLineDash([]); }
else { drawingContext.setLineDash([5, 5]); }
stroke(coordColor);
strokeWeight(0.5);
line(i, 0, i, height);
drawingContext.setLineDash([]);
textSize(12)
let offset;
if (i < origin.x) {
textAlign(LEFT, TOP);
offset = 2;
} else {
textAlign(RIGHT, TOP)
offset = -2
}
noStroke();
fill(coordColor);
text(i - origin.x, i + offset, origin.y + 2);
}
for (let j = 0; j <= height; j += span) {
if (j == origin.y) continue;
if (j % (span * 2) == 0) { drawingContext.setLineDash([]); }
else { drawingContext.setLineDash([5, 5]); }
stroke(coordColor);
strokeWeight(0.5);
line(0, j, width, j);
drawingContext.setLineDash([]);
textSize(12);
let offset;
if (j < origin.y) {
textAlign(RIGHT, TOP);
offset = 2;
} else {
textAlign(RIGHT, BOTTOM)
offset = -2
}
noStroke();
fill(coordColor);
text(j - origin.y, origin.x - 2, j + offset);
}
noStroke();
fill(coordColor);
textSize(15);
textAlign(RIGHT, TOP);
text("O", origin.x - 2, origin.y + 2);
}
//-----------------------------------------------------------------------------
// drawArrow function :draw arrowHead at the edge of vector v
//-----------------------------------------------------------------------------
function drawArrow(x, y) {
let arrowSize = map(p5.Vector.dist(v, origin), 0, maxLen, 5, 15);
arrowLine = createVector(x, y);
let baseAngle = p5.Vector.sub(arrowLine, origin).heading();
let angleR = baseAngle + radians(180 - 20);
let angleL = baseAngle + radians(180 + 20);
push();
translate(x, y);
let rX = arrowSize * cos(angleR);
let rY = arrowSize * sin(angleR);
line(0, 0, rX, rY);
let lX = arrowSize * cos(angleL);
let lY = arrowSize * sin(angleL);
line(0, 0, lX, lY);
pop();
}
//-----------------------------------------------------------------------------
// getInfoMsg : Display infomation on infoDiv element
//-----------------------------------------------------------------------------
function getInfoMsg() {
let len = p5.Vector.dist(v, origin);
let angle = p5.Vector.sub(v, origin).heading();
let str = "Polar Coords (r,θ) = (" + nfc(len, 2) + ", " + nfc(angle, 2) + ")<br>";
str += " length: " + nfc(len, 2) + "<br>";
str += " angle: " + nfc(angle, 5) + " rad.";
if (angle == HALF_PI) { str += "(= HALF_PI)"; }
if (angle == -HALF_PI) { str += "(= -HALF_PI)"; }
if (angle == PI) { str += "(= PI)"; }
str += "<br>    = ";
str += nfc(degrees(angle), 5) + "°<br><br>";
// cartesian x, y
str += "Cartesian Coords (x,y) = (" + floor(v.x - origin.x) + ", " + floor(v.y - origin.y) + ")<br>";
return str;
}
//-----------------------------------------------------------------------------
// keyPressed function : runs when any key is pressed
//-----------------------------------------------------------------------------
function keyPressed() {
// if the pressed key == "s"
if (key == "s") {
//switch index values
coordIndex = ((0 + 1) - coordIndex);
}
// reselect radiobutton
coordRadio.selected(coordIndex.toString());
}