Honeycomb Array

Post here for help on using FreeCAD's graphical user interface (GUI).
Forum rules
and Helpful information
IMPORTANT: Please click here and read this first, before asking for help

Also, be nice to others! Read the FreeCAD code of conduct!
chrisw
Posts: 37
Joined: Sun Mar 15, 2015 11:56 pm
Location: Australia

Re: Honeycomb Array

Post by chrisw »

Originally I wanted to have a circular outline to the hex array. A couple of weeks ago I managed to write a macro to do that.
Please excuse my crude code I am not a programmer and Python is very new to me.

I am drawing a 'seed' hex at the centre point and then create copies horizontally and vertically until their position is outside a fixed radius.
Then I make a second 'seed' hex at the right offset and repeat the process.

I am sure there are more elegant ways of going about it.

Whilst this works and does the job for me, I was wondering whether I can replace the IsInsideTargetArea(TestObject) function with a way whereby I can draw an outline in the GUI and then fill that outline with the hex pattern. In other words, test whether the centre coordinate of the next hex is within that outline just like I am doing now by checking for distance from the centre point.

Code: Select all

import Draft
import math
import string
import time

PI = 3.14159265

Radius = 120


def RefreshScreen(WaitTime = 0.05):
	Gui.updateGui()
#	Gui.SendMsgToActiveView("ViewFit")
	time.sleep(WaitTime)
	i = 0


def clearAll():
	doc = FreeCAD.ActiveDocument
	for obj in doc.Objects:
		doc.removeObject(obj.Name )
		RefreshScreen(0.01)



def DegToRad (Degrees):
	Degrees *= 2* PI
	Degrees /= 360
	return Degrees

def RadToDeg (Radians):
	Radians *= 360;
	Radians /= 2 * PI
	return Radians

def DistanceFromCentre(x,y):
	return math.sqrt(x*x + y*y)

def IsInsideTargetArea(TestObject):
	if TestObject.Placement.Base.Length >=Radius:
		return False
	else:
		return True

def HorizontalDistance(n):
	return 2*n*(2*HexOutsideRadius + WallThickness) * math.cos(DegToRad(30))

def VerticalDistance(n):
	return 2*n*(2*HexOutsideRadius + WallThickness) * math.sin(DegToRad(30))

def CopyHorizontallyToLimit(SeedHex, Direction):
	h = Direction
	while True:
		x = HorizontalDistance(h)
		NewHex = Draft.move(SeedHex,FreeCAD.Vector(x,0,0),True)	
		RefreshScreen()
		if not IsInsideTargetArea(NewHex):
			print NewHex.Name
			FreeCAD.ActiveDocument.removeObject(NewHex.Name)
			RefreshScreen()
			Gui.SendMsgToActiveView("ViewFit")
			break
		h+=Direction

def FillSeedHex(SeedHex, Direction):
	i = Direction
	CopyHorizontallyToLimit(SeedHex,Direction)  # extend initial seed hex along x first
	while True:
		y = VerticalDistance(i) 
		VerticalHex1 = Draft.move(SeedHex,FreeCAD.Vector(0,y,0),True)  
		RefreshScreen()
		if not IsInsideTargetArea(VerticalHex1):
			print VerticalHex1.Name
			FreeCAD.ActiveDocument.removeObject(VerticalHex1.Name)
			RefreshScreen()
			Gui.SendMsgToActiveView("ViewFit")
			break
		CopyHorizontallyToLimit(VerticalHex1,1)  # make horizontal copies util out to limit radius to the right
		CopyHorizontallyToLimit(VerticalHex1,-1) # make horizontal copies util out to limit radius to the left
		if not IsInsideTargetArea(VerticalHex1):
			print VerticalHex1.Name
			FreeCAD.ActiveDocument.removeObject(VerticalHex1.Name)
			RefreshScreen()
			Gui.SendMsgToActiveView("ViewFit")
			break
		i+=Direction

#----------------------------------------------------------------------------------------------------

clearAll()

StructureRadius = 120
HexOutsideRadius = 9
WallThickness = 4
HexInsideRadius  = HexOutsideRadius * math.cos(DegToRad(30))

print 
print '--------------------------------------------------------------------'
print

SeedHex1 = Draft.makePolygon(6,HexOutsideRadius,False)  # start with seed hexagon at the origin
RefreshScreen()

FillSeedHex(SeedHex1, 1)    # copy it horizontally and vertically until the extents of the limiting circle are reached
FillSeedHex(SeedHex1,-1)
#create second seed hexagon at the right distance
SeedHex2 = Draft.move(SeedHex1,FreeCAD.Vector((2*HexOutsideRadius + WallThickness) * math.cos(DegToRad(30)),(2*HexOutsideRadius + WallThickness) * math.sin(DegToRad(30)),0),True)
RefreshScreen()

FillSeedHex(SeedHex2, 1)
FillSeedHex(SeedHex2,-1)
Capture2.PNG
Capture2.PNG (30.46 KiB) Viewed 2088 times
Chris
ian.rees
Posts: 696
Joined: Sun Jun 15, 2014 3:28 am
Contact:

Re: Honeycomb Array

Post by ian.rees »

Hi Chris,

I'm no expert on macros in FreeCAD, or OpenCascade, so take this with a grain of salt. I think you'll find that it is possible to do what you describe, but it would be easier to use boolean operations to keep only the hexagons you want out of a larger honeycomb pattern.

If you were going to look at extending your algorithm, I'd guess the easiest way to do it to work with a "face" rather than an outline. Remember that OpenCascade (the underlying 3D CAD kernel of FreeCAD) is 3D oriented, and so "wires" (the outline) don't have to lie in a plane. This means that there is no general way to answer the question "is this [3D] point within this [3D] outline?".

So, rather than checking if a point is inside an outline, you would probably want to make a pattern of parallel line segments and test whether those segments intersect with the face you're interested in. I'm sure this is possible to do in a macro, but not sure about the particular functions to test for intersection, etc.

Hope this helps! -Ian-
theunnamed
Posts: 14
Joined: Thu Jun 04, 2015 6:29 pm

Re: Honeycomb Array

Post by theunnamed »

I wonder whether we can apply this texture on a cylinder and make cut of it ?
triplus wrote:
I had some fun with OpenSCAD and followed this interesting tutorial:
Leaf.png
triplus
Veteran
Posts: 9471
Joined: Mon Dec 12, 2011 4:45 pm

Re: Honeycomb Array

Post by triplus »

theunnamed wrote:I wonder whether we can apply this texture on a cylinder and make cut of it ?
triplus wrote:
I had some fun with OpenSCAD and followed this interesting tutorial:
Leaf.png
Interesting question but i do believe it deserves a separate forum thread.
User avatar
Kunda1
Veteran
Posts: 13434
Joined: Thu Jan 05, 2017 9:03 pm

Re: Honeycomb Array

Post by Kunda1 »

Opened an issue in the FreeCAD-macro repo asking which honeycomb macro/s to add to it.
Also linking this thread to issue #1141.
Alone you go faster. Together we go farther
Please mark thread [Solved]
Want to contribute back to FC? Checkout:
'good first issues' | Open TODOs and FIXMEs | How to Help FreeCAD | How to report Bugs
triplus
Veteran
Posts: 9471
Joined: Mon Dec 12, 2011 4:45 pm

Re: Honeycomb Array

Post by triplus »

Asking who? ;)

P.S. If you feel it should be included better to first test the macro if it works as expected. And if it does create a pull request after. Therefore more or less only request for inclusion (pull request) should happen there.
User avatar
Vincent B
Veteran
Posts: 4734
Joined: Sun Apr 05, 2015 9:02 am
Location: La Rochelle, France

Re: Honeycomb Array

Post by Vincent B »

one more. ;)
Attachments
hexa.FCStd
(31.01 KiB) Downloaded 74 times
Capture.JPG
Capture.JPG (35 KiB) Viewed 1032 times
Post Reply