algorithmic modeling for Rhino
Hello,
I'm putting together a script that calculates a percentage of a surface that is shaded at various times during the day. The backbone of this script is the mesh component.
However, I've run into major problems with the mesh shadow component becasue it cast shadows not only in the direction of the vector (away from the sun, like one would expect) but also opposite the direction of the vector (towards the sun, like one woule not expect). This means I cannot use the script I've written if there is any geometry beyond the plane that catches the shadows.
I've tried a few dozen ways of getting around this, like cutting / culling geometry that is behind the plane (the shadows are being cast upon), but what I've ended up realizing is that I just need a component that doesn't cast backwards shadows.
Attached are a few images that explain this problem. In this instance, the cube should cast a shadow on the plane, the sphere (which is opposite the plane from the "sun" should not).
Tags:
Hi Jissi
I have been recently struggling with the same problem (self casting shadows on a large objects) and I ended up with slicing breps.
I have tested your definition to see if this brings an answer but I must say with regret - it doesn't.
I've changed vector and a plane. Images attached.Looking forward to new try.
Piotr
Attached..
Yeah I suppose that's a nasty side-effect of the code. I use the following logic to find those shadows:
Protected Overrides Sub SolveInstance(ByVal DA As Grasshopper.Kernel.IGH_DataAccess)
Dim mesh As Mesh = Nothing
Dim dir As Vector3d = Vector3d.Unset
Dim plane As Plane = plane.UnsetDA.GetData(0, mesh)
If (Not DA.GetData(1, dir)) Then Return
If (Not DA.GetData(2, plane)) Then ReturnIf (Not dir.IsValid) OrElse _
(Not plane.IsValid) OrElse _
(mesh Is Nothing) Then
Return
End IfDim perp As New Plane(plane.Origin, dir)
Dim rc As Polyline() = mesh.GetOutlines(perp)If (rc Is Nothing) OrElse (rc.Length = 0) Then
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, _"Shadows were not cast onto the plane")
Return
End IfFor i As Int32 = 0 To rc.Length - 1
Dim pline As Polyline = rc(i)For v As Int32 = 0 To pline.Count - 1
Dim ray As New Line(pline(v), dir)
Dim t As Double
If (Rhino.Geometry.Intersect.Intersection.LinePlane(ray, plane, t)) Then
pline(v) = ray.PointAt(t)
End If
Next
NextDA.SetDataList(0, rc)
End Sub
If you find a good solution let me know and I'll adjust the algorithm.
--
David Rutten
david@mcneel.com
Poprad, Slovakia
Hi David,
Maybe you can make something of this. Because of the null/paths bug it doesn't work all the time but I was trying to demonstrate it for one above one intersecting and one below.
If I understand well, the double loop is working on a projection, so I don't see how to immediately find out if the mesh is between the projection and the source of light or if it's the projection that is between the source of light and the mesh. The solutions I can see required to come back to the mesh. It can be done by projecting the point found (pline(v)) back on the mesh (MeshRay(mesh, ray) and then look if this point is in the same direction than the sun (dot product equal to the product of the length (a test distance between the two points = 0 or the dot product is > 0 sounds safer here )). But I'm afraid it would consume a lot of CPU...
Another solution is to have a look at mesh.GetOutlines(plane) to see if it can easily be written into a GetOutlines(plane, dir) and then consider only the points that are in one of half space defined by plane.
I'm sure there are better solutions. But it's very early in the morning in Europe right now and time for me to go to bed.
Welcome to
Grasshopper
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
© 2024 Created by Scott Davidson. Powered by