Skip to content

Commit

Permalink
sonar
Browse files Browse the repository at this point in the history
  • Loading branch information
tailuge committed Dec 27, 2024
1 parent 83f7dc7 commit 1f41a47
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 57 deletions.
2 changes: 1 addition & 1 deletion dist/diagram.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/mathaven.js

Large diffs are not rendered by default.

62 changes: 21 additions & 41 deletions src/diagram/throw_gpt4o.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Vector3 } from "three";
import { Ball } from "../model/ball";
import { up, zero } from "../utils/utils";
import { I, m } from "../model/physics/constants";
import { Collision } from "../model/physics/collision";

export class CollisionThrow {
export class CollisionThrowPlot {

public static readonly R: number = 0.029; // ball radius in meters

Expand All @@ -12,34 +12,34 @@ export class CollisionThrow {
private static readonly b: number = 0.108; // Range of friction variation
private static readonly c: number = 1.088; // Decay rate

private log;
private readonly log;
constructor(log: (...args: any[]) => void = () => { }) {
this.log = log
}

private dynamicFriction(vRel: number): number {
return CollisionThrow.a + CollisionThrow.b * Math.exp(-CollisionThrow.c * vRel);
return CollisionThrowPlot.a + CollisionThrowPlot.b * Math.exp(-CollisionThrowPlot.c * vRel);
}


protected relativeVelocity(v: number, ωx: number, ωz: number, ϕ: number): number {
return Math.sqrt(
Math.pow(v * Math.sin(ϕ) - ωz * CollisionThrow.R, 2) +
Math.pow(Math.cos(ϕ) * ωx * CollisionThrow.R, 2)
Math.pow(v * Math.sin(ϕ) - ωz * CollisionThrowPlot.R, 2) +
Math.pow(Math.cos(ϕ) * ωx * CollisionThrowPlot.R, 2)
);
}


public throwAngle(v: number, ωx: number, ωz: number, ϕ: number): number {
const vRel = this.relativeVelocity(v, ωx, ωz, ϕ);
const μ = this.dynamicFriction(vRel);
const numerator = Math.min((μ * v * Math.cos(ϕ)) / vRel, 1 / 7) * (v * Math.sin(ϕ) - CollisionThrow.R * ωz);
const numerator = Math.min((μ * v * Math.cos(ϕ)) / vRel, 1 / 7) * (v * Math.sin(ϕ) - CollisionThrowPlot.R * ωz);
const denominator = v * Math.cos(ϕ);
this.log(`inputs:v=${v}, ωx=${ωx}, ωz=${ωz}, ϕ=${ϕ}`)
this.log(` v * Math.sin(ϕ) =${(v * Math.sin(ϕ))}`)
this.log(` CollisionThrow.R * ωz =${(CollisionThrow.R * ωz)}`)
this.log(` CollisionThrow.R * ωz =${(CollisionThrowPlot.R * ωz)}`)
this.log(` Math.min((μ * v * Math.cos(ϕ)) / vRel, 1 / 7) =${Math.min((μ * v * Math.cos(ϕ)) / vRel, 1 / 7)}`)
this.log(` (v * Math.sin(ϕ) - CollisionThrow.R * ωz) =${(v * Math.sin(ϕ) - CollisionThrow.R * ωz)}`)
this.log(` (v * Math.sin(ϕ) - CollisionThrow.R * ωz) =${(v * Math.sin(ϕ) - CollisionThrowPlot.R * ωz)}`)
this.log("")
this.log("vRel = ", vRel)
this.log("μ = ", μ)
Expand All @@ -50,6 +50,7 @@ export class CollisionThrow {
return Math.atan2(numerator, denominator);
}


public plot(v: number, ωx: number, ωz: number, ϕ: number) {
// assume balls in contact along y axis
// cue ball a is travelling +y only
Expand All @@ -59,16 +60,20 @@ export class CollisionThrow {
a.vel.copy(new Vector3(0, v, 0))
a.rvel.copy(new Vector3(ωx, 0, ωz))

const straight = new Vector3(0, 2 * CollisionThrow.R)
const straight = new Vector3(0, 2 * CollisionThrowPlot.R)
const bpos = straight.applyAxisAngle(up, ϕ)
const b = new Ball(bpos);

this.log("---original---")
let result = this.throwAngle(v, ωx, ωz, ϕ)
this.log("")
this.log("---new code")
result = this.updateVelocities(a, b)
return result
//this.log("---original---")
//let result = this.throwAngle(v, ωx, ωz, ϕ)
//this.log("")
//this.log("---new code")
const target:string = "plot"
if (target == "actual") {
Collision.model.updateVelocities(a, b)
return Math.atan2(-Collision.model.tangentialImpulse, Collision.model.normalImpulse)
}
return this.updateVelocities(a, b)
}

private updateVelocities(a: Ball, b: Ball) {
Expand All @@ -77,7 +82,6 @@ export class CollisionThrow {
const abTangent = new Vector3(-ab.y, ab.x, 0);

const R: number = 0.029
const e = 0.98
const vPoint = a.vel.clone().sub(b.vel).add(
ab.clone().multiplyScalar(-R).cross(a.rvel).sub(
ab.clone().multiplyScalar(R).cross(b.rvel)
Expand Down Expand Up @@ -108,30 +112,6 @@ export class CollisionThrow {
this.log("vRelNormalMag =", vRelNormalMag);
this.log("vRelTangential =", vRelTangential);

// Normal impulse (inelastic collision)
normalImpulse = -(1 + e) * vRelNormalMag / (2 / m);

// Tangential impulse (frictional constraint)
tangentialImpulse = Math.min(
(μ * Math.abs(normalImpulse)) / vRelMag,
1 / 7
) * -vRelTangential;

// Impulse vectors
const impulseNormal = ab.clone().multiplyScalar(normalImpulse);
const impulseTangential = abTangent.clone().multiplyScalar(tangentialImpulse);

// Apply impulses to linear velocities
a.vel.addScaledVector(impulseNormal, 1 / m).addScaledVector(impulseTangential, 1 / m);
b.vel.addScaledVector(impulseNormal, -1 / m).addScaledVector(impulseTangential, -1 / m);

// Angular velocity updates
const angularImpulseA = ab.clone().multiplyScalar(-R).cross(impulseTangential);
const angularImpulseB = ab.clone().multiplyScalar(R).cross(impulseTangential);

a.rvel.addScaledVector(angularImpulseA, 1 / I);
b.rvel.addScaledVector(angularImpulseB, 1 / I);

return throwAngle;
}

Expand Down
10 changes: 5 additions & 5 deletions src/diagram/throwplot.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

import { config, color, createTrace, layout } from "./plotlyconfig";
import { CollisionThrow } from "./throw_gpt4o";
import { CollisionThrowPlot } from "./throw_gpt4o";

export class ThrowPlot {

Expand All @@ -13,15 +13,15 @@ export class ThrowPlot {
}

public plotCutAngle() {
const R = CollisionThrow.R
const R = CollisionThrowPlot.R
this.plot("collision-throw-roll", [0.447, 1.341, 3.129], k => (k / R))
this.plot("collision-throw-stun", [0.447, 1.341, 3.129], _ => 0)

this.plotRolls("collision-throw-varying-roll", [0, 0.25, 0.5, 1], k => (k / R), _ => 0, phi => phi)
this.plotRolls("collision-throw-varying-side", [0, 0.25, 0.5, 1], k => (k / R), z => (1 / R) * (z - 45) / 45, _ => 0)

// test:
const model = new CollisionThrow(console.log)
const model = new CollisionThrowPlot(console.log)
model.plot(0.5, -15, -10, Math.PI / 8)
}

Expand All @@ -35,7 +35,7 @@ export class ThrowPlot {
deg = []
for (let alpha = 1; alpha < 90; alpha += 1) {
deg.push(alpha)
const model = new CollisionThrow()
const model = new CollisionThrowPlot()
const throwAngle = model.plot(k, omegax(k), 0, this.degToRad(alpha))
angle.push(this.radToDeg(throwAngle))
}
Expand Down Expand Up @@ -64,7 +64,7 @@ export class ThrowPlot {
x = []
for (let alpha = 1; alpha < 90; alpha += 1) {
x.push(alpha)
const model = new CollisionThrow()
const model = new CollisionThrowPlot()
const throwAngle = model.plot(1, omegax(k), omegaz(alpha), this.degToRad(phi(alpha)))
angle.push(this.radToDeg(throwAngle))
}
Expand Down
19 changes: 11 additions & 8 deletions src/model/physics/collisionthrow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import { I, m, R } from "./constants";
*/
export class CollisionThrow {

normalImpulse: number;
tangentialImpulse: number;

private dynamicFriction(vRel: number): number {
return 0.01 + 0.108 * Math.exp(-1.088 * vRel);
}
Expand All @@ -36,24 +39,24 @@ export class CollisionThrow {

const μ = this.dynamicFriction(vRelMag);

let normalImpulse = vRelNormalMag;
let tangentialImpulse =
Math.min((μ * vRelNormalMag) / vRelMag, 1 / 7) * (-vRelTangential)
//let normalImpulse = vRelNormalMag;
//let tangentialImpulse =
// Math.min((μ * vRelNormalMag) / vRelMag, 1 / 7) * (-vRelTangential)

// matches paper when throwAngle = Math.atan2(tangentialImpulse, normalImpulse)

// Normal impulse (inelastic collision)
normalImpulse = -(1 + e) * vRelNormalMag / (2 / m);
this.normalImpulse = -(1 + e) * vRelNormalMag / (2 / m);

// Tangential impulse (frictional constraint)
tangentialImpulse = Math.min(
(μ * Math.abs(normalImpulse)) / vRelMag,
this.tangentialImpulse = Math.min(
(μ * Math.abs(this.normalImpulse)) / vRelMag,
1 / 7
) * -vRelTangential;

// Impulse vectors
const impulseNormal = ab.clone().multiplyScalar(normalImpulse);
const impulseTangential = abTangent.clone().multiplyScalar(tangentialImpulse);
const impulseNormal = ab.clone().multiplyScalar(this.normalImpulse);
const impulseTangential = abTangent.clone().multiplyScalar(this.tangentialImpulse);

// Apply impulses to linear velocities
a.vel.addScaledVector(impulseNormal, 1 / m).addScaledVector(impulseTangential, 1 / m);
Expand Down

0 comments on commit 1f41a47

Please sign in to comment.