Curves & Surfaces landscape element,
surface definition and milling paths
Mahshid Moghadasi MDC ‘21 Cornell University
SURFACE GENERATION EXPLORATION
Surface 01
No function
Function 01
Function 02
Function 03
Surface 02
Surface 03
Surface 04
Surface 05
Function 04
Function 05
Function 06
Surface Generation Codes Surface 02
Surface 03
List < Point3d > points = new List<Point3d>(); int columns = 50; int rows = 50; double stepX = (regionP2.X - regionP1.X) / (columns - 1); double stepY = (regionP2.Y - regionP1.Y) / (rows - 1);
List < Point3d > points = new List<Point3d>(); int columns = 50; int rows = 50; double stepX = (regionP2.X - regionP1.X) / (columns - 1); double stepY = (regionP2.Y - regionP1.Y) / (rows - 1);
double x = regionP1.X; double y = regionP1.Y; double z = 0.0;
double x = regionP1.X; double y = regionP1.Y; double z = 0.0;
for (int j = 0; j < rows; ++j) { x = regionP1.X; for (int i = 0; i < columns; ++i){
for (int j = 0; j < rows; ++j) { x = regionP1.X; for (int i = 0; i < columns; ++i){
}
z = 1.5 * Math.Cos(x * 0.5); Point3d p = new Point3d(x, y, z);
z = 2 * Math.Cos(x * 0.2) * Math.Sin(y * 0.4); Point3d p = new Point3d(x, y, z);
points.Add(p); x += stepX;
points.Add(p); x += stepX;
} y += stepY;
Surface srf = NurbsSurface.CreateThroughPoints(points, columns, rows, 3, 3, false, false);
Surface 04
}
} y += stepY;
Surface srf = NurbsSurface.CreateThroughPoints(points, columns, rows, 3, 3, false, false);
Surface 05
List < Point3d > points = new List<Point3d>(); int columns = 50; int rows = 50; double stepX = (regionP2.X - regionP1.X) / (columns - 1); double stepY = (regionP2.Y - regionP1.Y) / (rows - 1);
List < Point3d > points = new List<Point3d>(); int columns = 50; int rows = 50; double stepX = (regionP2.X - regionP1.X) / (columns - 1); double stepY = (regionP2.Y - regionP1.Y) / (rows - 1);
double x = regionP1.X; double y = regionP1.Y; double z = 0.0;
double x = regionP1.X; double y = regionP1.Y; double z = 0.0;
for (int j = 0; j < rows; ++j) { x = regionP1.X; for (int i = 0; i < columns; ++i){
for (int j = 0; j < rows; ++j) { x = regionP1.X; for (int i = 0; i < columns; ++i){
}
z = Math.Sin((x - 15) * (y - 15) * 0.1); Point3d p = new Point3d(x, y, z);
z = 0.25 * Math.Abs(x) * Math.Pow(Math.Cos(0.5 * y), 2); Point3d p = new Point3d(x, y, z);
points.Add(p); x += stepX;
points.Add(p); x += stepX;
} y += stepY;
Surface srf = NurbsSurface.CreateThroughPoints(points, columns, rows, 3, 3, false, false);
}
} y += stepY;
Surface srf = NurbsSurface.CreateThroughPoints(points, columns, rows, 3, 3, false, false);
Functionsâ&#x20AC;&#x2122; Codes
Function 01 public double changeZNClosed (Point3d p, Curve crv, double a, double b){ double t = 0.0; crv.ClosestPoint(p, out t); Point3d cp = crv.PointAt(t); double d = cp.DistanceTo(p); double nt = crv.Domain.NormalizedParameterAt(t); nt = mapFromUnit(nt, 0, Math.PI); double change = Math.Sin(nt) * a * Math.Exp(-b * d * d); return change; }
Function 02 public double changeZNormalized (Point3d p, Curve crv, double a, double b){ double t = 0.0; crv.ClosestPoint(p, out t); Point3d cp = crv.PointAt(t); double d = cp.DistanceTo(p); double nt = crv.Domain.NormalizedParameterAt(t);
}
double change = nt * a * Math.Exp(-b * d * d); return change;
Function 03 public double changeZ (Point3d p, Curve crv, double a, double b){ double t = 0.0; crv.ClosestPoint(p, out t); Point3d cp = crv.PointAt(t); double d = cp.DistanceTo(p); double change = a * Math.Exp(-b * d * d); return change; }
Function 04 public double changeZFallSin (Point3d p, Curve crv, double a, double b){ double t = 0.0; crv.ClosestPoint(p, out t); Point3d cp = crv.PointAt(t); double d = cp.DistanceTo(p); double nt = crv.Domain.NormalizedParameterAt(t); double change = nt * Math.Sin(Math.PI * nt * 3) * Math.Exp(-b * d * d) * 8; return change; }
Function 05 public double changeZSin (Point3d p, Curve crv, double a, double b, double c){ double t = 0.0; crv.ClosestPoint(p, out t); Point3d cp = crv.PointAt(t); double d = cp.DistanceTo(p); double nt = crv.Domain.NormalizedParameterAt(t); double change = 2 * Math.Sin(Math.PI * d * c); return change; }
Function 06 public double changeZSinCos (Point3d p, Curve crv, double a, double b, double c){ double t = 0.0; crv.ClosestPoint(p, out t); Point3d cp = crv.PointAt(t); double d = cp.DistanceTo(p); double nt = crv.Domain.NormalizedParameterAt(t);
}
double change = 2 * Math.Exp(-b * Math.Cos(Math.PI * d * d * 0.1) * Math.Cos(Math.PI * d * d * 0.1)); return change;
STREAMLINE FORCES EXPLORATION
Point Attraction
Point Attraction + Contour
Point Attraction + Rotation
Point Attraction + Slope
Magnet
Magnet + Contour
Magnet + Rotation
Magnet + Slope
Slope
Slope + Contour
Slope + Rotation
All Attracting Magnet
Contour
Rotation + Contour
Rotation
All Repellent Magnet
Streamline Forces Codes
Attraction public Vector3d attractionVec(Surface s, double u, double v, Point3d p, double strength){ Point3d uvp = s.PointAt(u, v); Vector3d directionv = p - uvp; directionv.Unitize(); Vector3d nv = s.NormalAt(u, v); double dotproduct = directionv * nv; Vector3d projected = dotproduct * nv; Vector3d attv = directionv - projected; attv.Unitize(); return (attv * strength); }
Magnetic Force public Vector3d magnetVec (Surface s, double u, double v, List<Point3d> pos, List<Point3d> neg, double strength){ Point3d uvp = s.PointAt(u, v); Vector3d magv = Vector3d.Zero; foreach (Point3d p in pos){ Vector3d df = p - uvp; double L = df.Length; magv -= df * (1.0 / (L * L)); } foreach (Point3d p in neg){ Vector3d df = p - uvp; double L = df.Length; magv += df * (1.0 / (L * L)); } }
return (magv * 1 / (strength + 0.00001));
Rotation public Vector3d rotationVec(Surface s, double u0, double v0, List<Point3d> rps, double strength){ Vector3d fv = Vector3d.Zero; Point3d uvp = s.PointAt(u0, v0); foreach (Point3d p in rps){ Vector3d directionv = p - uvp; double L = directionv.Length; fv += directionv * (1.0 / (L * L )); } Vector3d nv = s.NormalAt(u0, v0); Vector3d v = Vector3d.CrossProduct(fv, nv); return (v * strength); }
Streamline Forces Codes
Contour public Vector3d contourVec(Surface s, double u, double v, double strength){ Point3d p = new Point3d(0.0, 0.0, 0.0); Point3d uvp = s.PointAt(u, v); Vector3d directionv = p - uvp; directionv.Unitize(); Vector3d nv = s.NormalAt(u, v); return (Vector3d.CrossProduct(nv, new Vector3d(0, 0, 1)) * strength); }
Slope public Vector3d slopeVec(Surface s, double u, double v, double strength){ Point3d uvp = s.PointAt(u, v); Vector3d n = s.NormalAt(u, v); Vector3d slope = new Vector3d(n.X * n.Z, n.Y * n.Z, -n.X * n.X - n.Y * n.Y); double L = slope.Length; slope = slope * (1.0 / L * L); return (slope * strength); }
Streamline Creation //......................Creating Final Vector at each Point.............. public Vector3d fieldAt(Surface s, double u, double v, List<Point3d> pos, List<Point3d> neg, Point3d attPoint, List<Point3d> rotationPoint, double magnetWeight, double attractionWeight, double rotationWeight, double contourWeight, double slopeWeight) { Vector3d Vector3d Vector3d Vector3d Vector3d
}
fv rv cv mv sp
= = = = =
attractionVec(s, u, v, attPoint, attractionWeight); rotationVec(s, u, v, rotationPoint, rotationWeight); contourVec(s, u, v, contourWeight); magnetVec(s, u, v, pos, neg, magnetWeight); slopeVec(s, u, v, slopeWeight);
Vector3d sumv = fv + rv + cv + mv + sp; //All are projected on surface--> result is also on surface sumv.Unitize(); sumv *= 0.2; return sumv;
//........................Creating the streamlines for milling............. public Polyline createStreamline (Surface s, Point3d seedPoint, int n, List<Point3d> pos, List<Point3d> neg, Point3d attPoint, List<Point3d> rotationPoint, double magnetWeight, double attractionWeight, double rotationWeight, double contourWeight, double slopeWeight) { Polyline pl = new Polyline();
}
Point3d p = seedPoint; for (int i = 0; i < n; ++i){ double u = 0.0; double v = 0.0; s.ClosestPoint(p, out u, out v); p = s.PointAt(u, v); pl.Add(p); Vector3d move = fieldAt(s, u, v, pos, neg, attPoint, rotationPoint, magnetWeight, attractionWeight, rotationWeight, contourWeight, slopeWeight); p = p - move; } return pl;
FINAL DESIGN
1) z = 2 * Math.Cos(x * 0.4) * Math.Sin(y * 0.4);
2) z = 2 * Math.Cos(x * 0.4) * Math.Sin(y * 0.4) + y * 0.2;
3) p.Z -= changeZSinCos2(p, crv1, a, b, c);
Hydrophobic tree on the heights
4) streamlines show the water flow Hydrophilic trees in the valleys
//...................Surface ..................... List < Point3d > points = new List<Point3d>(); int columns = 50; int rows = 50; double stepX = (regionP2.X - regionP1.X) / (columns - 1); double stepY = (regionP2.Y - regionP1.Y) / (rows - 1); double x = regionP1.X; double y = regionP1.Y; double z = 0.0; for (int j = 0; j < rows; ++j){ x = regionP1.X; for (int i = 0; i < columns; ++i){ z = 2 * Math.Cos(x * 0.4) * Math.Sin(y * 0.4) + y * 0.2; Point3d p = new Point3d(x, y, z); p.Z -= changeZSinCos2(p, crv1, a, b, c); points.Add(p); x += stepX;
} y += stepY;
} Surface srf = NurbsSurface.CreateThroughPoints(points, columns, rows, 3, 3, false, false); List <Point3d> uvpoints = new List<Point3d>(); List <Vector3d> fvectors = new List<Vector3d>(); Vector3d z = new Vector3d(0, 0, 1); //..............Points at UVs...................... int nx = 60; int ny = 60; double stepnx = (srf.Domain(0)[1] - srf.Domain(0)[0]) / (nx - 1); double stepny = (srf.Domain(1)[1] - srf.Domain(1)[0]) / (ny - 1); for (int j = 0; j < ny; ++j){ for (int i = 0; i < nx; ++i){ double u = i * stepnx + srf.Domain(0)[0]; double v = j * stepny + srf.Domain(1)[0]; Point3d uvp = srf.PointAt(u, v); uvpoints.Add(uvp); //..............Field Vector at UVs............ Vector3d sumv = fieldAt(srf, u, v, posPoints, negPoints, attPoint, rotationPoints, magnetWeight, attractionWeight, rotationWeight, contourWeight, slopeWeight); fvectors.Add(sumv); //......tangents................ Vector3d[] dv; //both tangents srf.Evaluate(u, v, 1, out uvp, out dv); tangents0.Add(dv[0] * 0.5); tangents1.Add(dv[1] * 0.5);
} } //..............Stream Lines...................... List <Polyline> slines = new List<Polyline>(); foreach (Point3d p in seedPoints){ Polyline pl = createStreamline(srf, p, n, posPoints, negPoints, attPoint, rotationPoints, magnetWeight, attractionWeight, rotationWeight, contourWeight, slopeWeight); slines.Add(pl); }
FINAL RESULT Magnetic Force + Slope Vectors Streamlines focus on the hydrophilic trees and get away from from the hydrophobic ones, showing the water flow.
Front View
Perspective View
Plan View