PMKS-Web / PMKSWeb

An educational web-based tool designed for comprehensive 2D linkage analysis developed at WPI (Worcester Polytechnic Institute)
https://pmksplus.com
3 stars 2 forks source link

com locations change when adding tracers #156

Open rkprad opened 1 year ago

rkprad commented 1 year ago

com locations change positions when adding tracers

https://files.slack.com/files-pri/T6Y7SFW5V-F05JKA97RE2/image.png https://files.slack.com/files-pri/T6Y7SFW5V-F05JUD95L6Q/image.png

AlexG1031 commented 1 year ago

I determined logic to determine the CoM and am curious whether the logic will work.

@KohmeiK I have some questions that will require an explanation. There is a circular fallacy I have with determining the CoM because determining CoM requires the path traveled by svg's d and determining the svg's d requires knowing the link's CoM. Is it possible to determine RealLink.isclockwise without having to utilize CoM? (link.ts)? Or is it possible to set all the path of the link's traveled path to travel cw or ccw?

AlexG1031 commented 1 year ago

I will focus on this later but happy I at least put some thought into this for future reference.

I am solving for center of mass:

Image

As an alternative, I determine the points around the shape and use that to help determine area and ultimately determine CoM, just like with Green's method:

Image

To determine this equation, I utilize this library to help determine the interpolated values within a path for d:

// Put this command within terminal to import d3-interpolate-path. npm install d3-interpolate-path npm i --save-dev @types/d3-interpolate-path

The logic for determining this can be seen below. This will be inserted within link.ts file to determine the CoM.

// https://pbeshai.github.io/d3-interpolate-path/ import { interpolatePath } from 'd3-interpolate-path';

static determineCenterOfMass(d: string) { const points = this.interpolateSvgPath(d, 10); return this.getPolygonCentroid(points); // let com_x = 0; // let com_y = 0; // TODO: Logic isn't exactly right but can change this once other logic is fully finished // joints.forEach((j) => { // com_x += j.x; // com_y += j.y; // }); // return new Coord(com_x / joints.length, com_y / joints.length); }

// type Point = [number, number];

static getPolygonArea(points: Coord[]): number { let total = 0; for (let i = 0; i < points.length; i++) { let addX = points[i].x; let addY = points[(i + 1) % points.length].y; let subX = points[(i + 1) % points.length].x; let subY = points[i].y;

  total += (addX * addY * 0.5);
  total -= (subX * subY * 0.5);
}
return total;

}

static getPolygonCentroid(points: Coord[]): Coord { let totalX = 0; let totalY = 0; let area = this.getPolygonArea(points);

for (let i = 0; i < points.length; i++) {
  let x = points[i].x;
  let y = points[i].y;
  let nextX = points[(i + 1) % points.length].x;
  let nextY = points[(i + 1) % points.length].y;

  let factor = (x * nextY - nextX * y);
  totalX += (x + nextX) * factor;
  totalY += (y + nextY) * factor;
}

totalX /= (area * 6.0);
totalY /= (area * 6.0);

return new Coord(totalX, totalY);

}

static interpolateSvgPath(d: string, numPoints: number): Coord[] { // Create an interpolator for the path const interpolator = interpolatePath(d, d);

// Use the interpolator to generate the points
const points = [];
for (let i = 0; i < numPoints; i++) {
  const t = i / (numPoints - 1);  // Normalize i to the range [0, 1]
  const interpolated = interpolator(t);
  // Parse the interpolated string to get the x and y coordinates
  const match = /M(\d+\.?\d*),(\d+\.?\d*)/.exec(interpolated);
  if (match) {
    const x = parseFloat(match[1]);
    const y = parseFloat(match[2]);
    points.push(new Coord(x, y));
  }
}
return points;

}

KohmeiK commented 1 year ago

The question we should be asking here is if we need to implement something this complex to achieve our goal here. Is this something we really need to fix? The user will be able to specify a custom COM location.

rkprad commented 1 year ago

The com location should not change when tracer is added. So, that needs to be corrected. I am only looking for the simplest fix.

KohmeiK commented 1 year ago

Ok maybe we don't change the COM automatically at all after we create a tracer

rkprad commented 1 year ago

that's fine too, Kohmei. this issue only happens in straight links. ONce you move the tracer, then the com location is correct.

Since I've used the old PMKS+ a lot, students use that COM info directly in their calculations/assumptions despite telling them that that needs to change. That's why I felt it would be good to correct that.

KohmeiK commented 1 year ago

Yeah, this is something the three of us should discuss and balance the complexity of the integration solution vs what we have now which is just a average of the joint positions.

rkprad commented 1 year ago

I thought this was just a small bug in a straight link. Now I see that the issue is prevalent in other composite shapes as well. So, in that case, let's just have a notification asking users to update the com manually, rather than having the program automatically do it. In that case, let this be a future task because there may not be an easy/simple solution to this one.