I think for the swivelling connections, rather than the full RigidBody and AlignFaces approach with oriented particles, it would probably be simpler and faster to make a ‘lineAlignSnap’ goal which acts on pairs of line segments.
Say if Line1endA and Line2endA are within some distance d1 of each other, an align force would be applied to the 2 segments, turning them towards being collinear with opposite directions.
Also if they are within d2 (with d2<d1), then it would snap the ends together.
(Giving the alignment a larger range than the snapping should help avoid the case where 2 units try to snap together on more than one arm)
Then units could be modelled as simple Length goals on tetrahedra edges plus lines connecting the verts to an additional point in their center.
For collisions, one could then use the existing capsule collider (because of the alignment force we don’t need to worry about simulating the flat cylinder ends).
Old kangaroo had a “spring” goal that would activate with a length threshold, like snapping only etc etc…
Anyway,
AB - BA
if we make B attract B but A repel A (with a bigger enough radius), we have a stable system, co-linear.
Make B attract all other Bs only when near enough…
Hey Daniel, Thanks for the advice, it makes sense to me on paper. My Custom Goal skills have gotten a bit dusty over the years but were you thinking something along these lines (no pun intended)?
private void RunScript(List<Line> iLines, double iAlign, double iSnap, double iWeight, ref object A)
{
A = new LineAlignSnap(iLines, iAlign, iSnap, iWeight);
}
#endregion
#region Additional
public class LineAlignSnap : GoalObject
{
public double Strength;
public double d1;
public double d2;
public LineAlignSnap(List<Line> lines, double alignDistance, double snapDistance, double k)
{
int L = lines.Count;
PPos = new Point3d[L * 2];
for (int i = 0; i < L; i++)
{
PPos[i] = lines[i].From;
PPos[i + L] = lines[i].To;
}
d1 = alignDistance;
d2 = snapDistance;
Move = new Vector3d[L * 2];
Weighting = new double[L * 2];
Strength = k;
}
public override void Calculate(List<KangarooSolver.Particle> p)
{
int L = PIndex.Length / 2;
for (int i = 0; i < L; i++)
{
Point3d pA1 = p[PIndex[i]].Position;
Point3d pA2 = p[PIndex[i + L]].Position;
//Vector3d currentA = pA2 - pA1;
for (int j = 0; j < L; j++)
{
Point3d pB1 = p[PIndex[j]].Position;
Point3d pB2 = p[PIndex[j + L]].Position;
Vector3d currentB = pB2 - pB1;
double d = pA2.DistanceTo(pB2);
if (d < d1 && d > d2)
{
Point3d[] Pts = new Point3d[4] {pA1,pA2, pB1, pB2 };
Line Ln;
Line.TryFitLineToPoints(Pts, out Ln);
Point3d moveP1 = Ln.ClosestPoint(pA1, false);
Point3d moveP2 = Ln.ClosestPoint(pA2, false);
Vector3d moveVec1 = moveP1 - pA1;
Vector3d moveVec2 = moveP2 - pA2;
Move[i] = moveVec1;
Move[i + L] = moveVec2;
Weighting[i] = Strength;
Weighting[i + L] = Strength;
}
else if (d < d2)
{
Vector3d moveVec = pB2 - pA2;
Move[i] = moveVec;
Move[i + L] = new Vector3d(0, 0, 0);
Weighting[i] = Strength;
Weighting[i + L] = Strength;
}
//else { break; }
}
}
}
}
#endregion
}
I am a bit stuck on making alignment that works to push the points to be colinear in opposing directions. I can imagine perhaps rotating the endpoints of a line about their center to move away from one another, but wouldn’t I then need to encompass the positive and negative attraction points within the same goal? Or were you thinking I could just use the line’s direction as a stand in? Say if two lines’ endpoints or start points were within d1, they would rotate away from one another.
Great script and it is really help me in continuing my project, so thank you so much. However I am getting stuck on one criteria I need to meet. All the Negative/Positive attraction is working depending on the data I manually give, but what if I have a specific point(s) on the boundary of the rectangular(or any shape such is my case) box that I need them to stay fixed and don’t move, but act as attraction or repulsion to other points in Space? I tried assigning them with the same script as different points and give them different values to what points to attract and what points to repulse but it didn’t work.
Here is my Script maybe it’s easier to get what I mean Attraction-Repulsion Landuses.gh (41.4 KB)