relative-motion-2.js

total 0
used 0
limit 0
/* title: Relative Forward categories: relative files: ../point_src/core/head.js ../point_src/pointpen.js ../point_src/pointdraw.js ../point_src/extras.js ../point_src/math.js ../point_src/point-content.js ../point_src/stage.js ../point_src/point.js ../point_src/distances.js ../point_src/pointlist.js ../point_src/events.js ../point_src/automouse.js ../point_src/keyboard.js --- The point will always walk towards the plot direction, turning through the _shortest_ angle */ const forward = function(p, turnSpeed=1, minSpeed=0, maxSpeed=1) { /* walk in the direction of the rotation*/ let target = p.target if(target == undefined) { // target = p.project() target = Point.mouse.position } const mp = target //Point.mouse.position // target; p.turnTo(mp, turnSpeed); const r = p.radians const distance = p.distanceTo(mp) const radius = p.radius let stepAmount = (distance / radius ) * .3 if(distance *.5 < radius) { p.target = undefined } stepAmount = clamp(stepAmount, minSpeed, maxSpeed) p.x += stepAmount * Math.cos(r); p.y += stepAmount * Math.sin(r); } // Helper function to clamp a value within a range // const clamp = (value, min, max) => Math.min(Math.max(value, min), max); const relMoveNoRotation = function(p, direction, speed = 1, minSpeed = 0, maxSpeed = 1) { // Normalize the direction vector to ensure it's unit length const magnitude = Math.sqrt(direction.x * direction.x + direction.y * direction.y); // Avoid division by zero if direction vector is zero if (magnitude === 0) return; const normalizedDir = { x: direction.x / magnitude, y: direction.y / magnitude }; // Clamp speed to be within the allowed range const clampedSpeed = clamp(speed, minSpeed, maxSpeed); // Update position `p` based on the normalized direction and speed p.x += normalizedDir.x * clampedSpeed; p.y += normalizedDir.y * clampedSpeed; }; const relMoveD = function(p, direction, speed = 1, minSpeed = 0, maxSpeed = 1) { // Normalize the direction vector const magnitude = Math.sqrt(direction.x * direction.x + direction.y * direction.y); // Avoid division by zero if direction vector is zero if (magnitude === 0) return; const normalizedDir = { x: direction.x / magnitude, y: direction.y / magnitude }; // Clamp speed to be within the allowed range // const clampedSpeed = clamp(speed, minSpeed, maxSpeed); // Get the current rotation of the point `p` in radians const r = p.radians; // Apply the direction based on the point's rotation // Transform the direction vector to account for the point's rotation const rotatedDir = { x: normalizedDir.x * Math.cos(r) - normalizedDir.y * Math.sin(r), y: normalizedDir.x * Math.sin(r) + normalizedDir.y * Math.cos(r) }; // Update position `p` based on the rotated direction and clamped speed p.x += rotatedDir.x * clamp(direction.x, minSpeed, maxSpeed); p.y += rotatedDir.y * clamp(direction.y, minSpeed, maxSpeed); }; const clamp = (a, min = 0, max = 1) => Math.min(max, Math.max(min, a)); const lerp = (x, y, a) => x * (1 - a) + y * a; const cosSin = function(value=1) { /* The cosSin object is a simple helper for cos/sin of a value. cs = cosSin(100) cs.cos() cs.sin() Provide a multiplier - useful when rotating around a _point_ (such as a normalised value) cs.sin(.4) */ return { cos:(multiplier=1) => Math.cos(value) * multiplier , sin:(multiplier=1) => Math.sin(value) * multiplier , spin(item) { /* Spin through a normalised direction, const cs = cosSin(p.radians) // Apply the direction based on the point's rotation // Transform the direction vector to account for the point's rotation let spun = cs.spin(normalizedDir) const rotatedDir = { x: spun.x.cos - spun.y.sin, y: spun.x.sin + spun.y.cos }; Synonymous to: let spunX = cs.spin(normalizedDir.x) let spunY = cs.spin(normalizedDir.y) const rotatedDir = { x: spunX.cos - spunY.sin, y: spunX.sin + spunY.cos }; */ if(item.x !== undefined) { return { x:this.spinOne(item.x) , y:this.spinOne(item.y) } } return this.spinOne(item) } , spinOne(multiplier) { let c = this.cos(multiplier) let s = this.sin(multiplier) return { cos:c, x:c, sin:s, y:s, } } } } class Addon { /* An Addon applies some core functionality on the polypoint mixin such as a constructor, and destroy methods. */ constructor(parent) { this.parent = parent; } } class RelativeMotion extends Addon { _relativeMove(direction, speed=undefined, minSpeed=0, maxSpeed=1) { let p = this.parent // Normalize the direction vector const magnitude = direction.magnitude() // Avoid division by zero if direction vector is zero if (magnitude === 0) return; const normalizedDir = direction.normalized() // Clamp speed to be within the allowed range // const clampedSpeed = clamp(speed, minSpeed, maxSpeed); // Get the current rotation of the point `p` in radians const cs = cosSin(p.radians) // Apply the direction based on the point's rotation // Transform the direction vector to account for the point's rotation let spun = cs.spin(normalizedDir) const rotatedDir = { x: spun.x.cos - spun.y.sin, y: spun.x.sin + spun.y.cos }; if(speed == undefined) { speed = 1 } // Update position `p` based on the rotated direction and clamped speed p.x += rotatedDir.x * clamp(speed, minSpeed, maxSpeed); p.y += rotatedDir.y * clamp(speed, minSpeed, maxSpeed); } move(direction, speed, minSpeed, maxSpeed) { return this._relativeMove(direction, undefined, minSpeed, maxSpeed) } towards(other, turnSpeed=.1, speed, minSpeed, maxSpeed) { this.parent.turnTo(other, turnSpeed) return this.move(new Point({x:1, y:0}), speed, minSpeed, maxSpeed) } } Polypoint.head.lazierProp('Point', function relative() { return new RelativeMotion(this) } ); class MainStage extends Stage { canvas = 'playspace' mounted() { console.log('mounted') this.mouse.position.vy = this.mouse.position.vx = 0 this.a = new Point({ x: 200, y: 200, vx: 0, vy: 0}) this.events.click(this.mouseClick.bind(this)) this.clickPoint = new Point(0,0) } mouseClick(ev) { console.log('mouseClick', ev) this.clickPoint = Point.from(ev) // this.clickPoint = new Point(ev.x, ev.y) this.a.target = this.clickPoint } draw(ctx) { this.clear(ctx) // this.a.relative.move({x: 1, y: 0}, 0, 4) this.a.relative.towards(this.clickPoint) this.a.pen.indicator(ctx) this.clickPoint.pen.indicator(ctx) } } const stage = MainStage.go()
Run
Meta Data
title Relative Forward
imports ()
files ('../point_src/core/head.js', '../point_src/pointpen.js', '../point_src/pointdraw.js', '../point_src/extras.js', '../point_src/math.js', '../point_src/point-content.js', '../point_src/stage.js', '../point_src/point.js', '../point_src/distances.js', '../point_src/pointlist.js', '../point_src/events.js', '../point_src/automouse.js', '../point_src/keyboard.js')
unused_keys ()
unknown_keys ('categories',)
categories ['relative']
filepath_exists True
path relative-motion-2.js
filepath relative-motion-2.js
clean_files ('../point_src/core/head.js', '../point_src/pointpen.js', '../point_src/pointdraw.js', '../point_src/extras.js', '../point_src/math.js', '../point_src/compass.js', '../point_src/center.js', '../point_src/point-content.js', '../point_src/stage-resize.js', '../point_src/functions/resolve.js', '../point_src/stage.js', '../point_src/relative-xy.js', '../point_src/pointcast.js', '../point_src/point.js', '../point_src/distances.js', '../point_src/pointlistdraw.js', '../point_src/pointlistgradient.js', '../point_src/pointlistshape.js', '../point_src/pointlistgenerator.js', '../point_src/unpack.js', '../point_src/pointlist.js', '../point_src/events.js', '../point_src/automouse.js', '../point_src/keyboard.js')
markdown {'html': '<p>The point will always walk towards the plot direction, turning through\nthe <em>shortest</em> angle</p>', 'content': 'title: Relative Forward\ncategories: relative\nfiles:\n ../point_src/core/head.js\n ../point_src/pointpen.js\n ../point_src/pointdraw.js\n ../point_src/extras.js\n ../point_src/math.js\n ../point_src/point-content.js\n ../point_src/stage.js\n ../point_src/point.js\n ../point_src/distances.js\n ../point_src/pointlist.js\n ../point_src/events.js\n ../point_src/automouse.js\n ../point_src/keyboard.js\n---\n\nThe point will always walk towards the plot direction, turning through\nthe _shortest_ angle'}