Mesh between three or more points

What is best way to create mesh between three or more points on the same or different height. The arc between points has always the same radius, nevermind betwee which points. I was trying use delaunay.bypints but it works only on flat surface. Have you any hints or advices how to catch it? I’d like to get something like below

Is the intent that this is a portion of a sphere?

Also, why a mesh?

Yes It’s going about portion of sphere. Maybye I said it wrong using mesh, it should be just surface

So this is a geometry exercise, not a coding one.

Given 3 points the center points of a sphere of a given radius which touches all points can be found by drawing a sphere of the given radius at each point, then get the common intersections among all the spheres - there should be two points - one above and one below the plane formed by the 3 points. From there generate the base sphere and extract it’s surface.

Get the triangle formed by the points, find the midpoint on each, and get the point on the surface which is closest to each. This is the 'midpoint of each edge around the sphere. The start point is… well the start of the respective line of the triangle, and the end point is the end of the respective triangle line. Build an arc through the 3 sets of 3 points.

Finally convert the 3 arcs into a polycurve, and trim the sphere surface by the polycurve.

Doable with basic nodes alone = List.ShiftIndicies can help, and Surface.TrimWithEdgeLoops (lesser known node right there).

But I figured I’d try it with some DesignScript:

def regenPoint(regen: bool, x: double, y: double)
{
	return Point.ByCoordinates(
		x,y,Math.Random()*2+8
	);
};

def canopyCloudBy3Points(pnt1: Point, pnt2: Point, pnt3: Point, radius: double, indx: int)
{
	pnts = [pnt1,pnt2,pnt3];
	initiationSpheres =
		List.Flatten(
			Sphere.ByCenterPointRadius(
				pnts,
				radius
			).Explode(),
			-1
		);

	centerPoint =
		List.Flatten(
			initiationSpheres[0].Intersect(
				initiationSpheres[1]
			).Intersect(
				initiationSpheres[2]
			),
			-1
		)[indx];

	baseSphere =
		Sphere.ByCenterPointRadius(
			centerPoint,
			radius
		).Explode()[0];

	permMidPoints =
		baseSphere.ClosestPointTo(
			Line.ByStartPointEndPoint(
				pnts,
				List.ShiftIndices(pnts,1)
			).PointAtParameter(0.5)
		);

	perim =
		PolyCurve.ByJoinedCurves(
			Arc.ByThreePoints(
				pnts,
				permMidPoints,
				List.ShiftIndices(pnts,1)
			),
			0,
			false,
			0
		);

	result =
		baseSphere.TrimWithEdgeLoops(
			perim,
			0
		);
	return result;
};

That goes into a code block, and then gets called after the definition or in a second code block by canopyCloudBy3Points(pnt1, pnt2, pnt3, radius, indx);.

3 Likes

Hi

Here’s one possibility, although Mr. Jacob’s is more elegant.

Edit: I made a mistake; the polygon projection doesn’t correspond to the required spherical cap with three equal radii.

The image on the left shows all the objectives achieved. In short, Mr. Jacob’s solution is correct; mine isn’t.

Sorry.

cordially

christian.stan

1 Like

A mathematical python representation :snake:

import clr
clr.AddReference('ProtoGeometry')
fromAutodesk.DesignScript.Geometryimport *
import math

# Inputs
pts = IN[0] # Must be 3 corner points
radius = IN[1]

p0, p1, p2 = pts[0], pts[1], pts[2]

# Calculate Circumcentre
ax, ay, az = p1.X-p0.X, p1.Y-p0.Y, p1.Z-p0.Z
bx, by, bz = p2.X-p0.X, p2.Y-p0.Y, p2.Z-p0.Z

dot_aa = ax*ax + ay*ay + az*az
dot_bb = bx*bx + by*by + bz*bz
dot_ab = ax*bx + ay*by + az*bz

det = dot_aa*dot_bb - dot_ab*dot_ab
ux = dot_bb*(dot_aa - dot_ab) / (2.0*det)
uy = dot_aa*(dot_bb - dot_ab) / (2.0*det)

cc_x = p0.X + ux*ax + uy*bx
cc_y = p0.Y + ux*ay + uy*by
cc_z = p0.Z + ux*az + uy*bz

# Calculate Normal
nx = ay*bz - az*by
ny = az*bx - ax*bz
nz = ax*by - ay*bx
n_len = math.sqrt(nx*nx + ny*ny + nz*nz)
nx, ny, nz = nx/n_len, ny/n_len, nz/n_len

cr = math.sqrt((cc_x-p0.X)**2 + (cc_y-p0.Y)**2 + (cc_z-p0.Z)**2)
h = math.sqrt(radius*radius - cr*cr)

cA = Point.ByCoordinates(cc_x + h*nx, cc_y + h*ny, cc_z + h*nz)
cB = Point.ByCoordinates(cc_x - h*nx, cc_y - h*ny, cc_z - h*nz)
centre = cA ifcA.Z < cB.Zelse cB

cx, cy, cz = centre.X, centre.Y, centre.Z

# Create 3 Arcs
shifted = [pts[1], pts[2], pts[0]]
arcs = []

foriin range(3):
p_start = pts[i]
p_end = shifted[i]

# Chord midpoint
mx = (p_start.X + p_end.X) / 2.0
my = (p_start.Y + p_end.Y) / 2.0
mz = (p_start.Z + p_end.Z) / 2.0

# Direction from sphere centre to chord midpoint, scaled to radius
dx, dy, dz = mx - cx, my - cy, mz - cz
d_len = math.sqrt(dx*dx + dy*dy + dz*dz)
arc_mid = Point.ByCoordinates(
cx + radius * dx / d_len,
cy + radius * dy / d_len,
cz + radius * dz / d_len
)

arcs.append(Arc.ByThreePoints(p_start, arc_mid, p_end))

# Create Surface by Patch-
boundary = PolyCurve.ByJoinedCurves(arcs)
sail = Surface.ByPatch(boundary)

OUT = sail

1 Like