JimYuan's Blog

Sharing the things I learned

0%

Webpage link: https://www.rhino3d.com/inside/revit/1.0/guides/revit-revit
This article is the note after I read the essential guide from RIR.

The Element DNA

Keep in mind that not every element has geometry. Some of these elements might only carry information.

  • Category
    defines the highest orgasnization level and carries a template for input and output properties of the element. The category list is built into Revit and cannot change.
  • Family
    defines the second organized level. Family is like a function f(x), that takes inputs from type and instance parameters, produces metadata, and geometry.
    The family logic is either built into Revit as System Families e.g. Floors, Walls, and Roofs, or can be defined using Custom Famuilies e.g. Doors and Windows.
  • Type
    defines the third organization level. Type also carries value of type parameters. These values are fed in to the Family function to generate the element and calculated type parametes.
  • Instance
    carries transform information that places the element in the 2D or 3D space. It also carries values of instance paramters. These values are fed in to the Family function to generate the element and calculated instance parameters.

So practically, we feed type and instance information into the family function, to generate the element metadata(including calculated properties) and geometry.

The generated elements are stored in a Revit Document. They are also organized by a series of Containers.

Subcategories can be think as a property of geometry.
When a Family function generates geometry, it can group them into subcategories of the main category.

Elements & Instances

  • Elements are the basic building block in Revit data model.
  • Elements have Parameters that hold data associated with Element.
    • Bulit-in parameters
    • custom parameters defined by user.
  • An Element could
    • has geometry (e.g. Walls(3D), Detail Components(2D))
    • has no geometry (e.g. Project information)

Video Link: https://www.youtube.com/watch?v=Pq6i_5o2ri4

This article will be the note after watching this Live from Hypar.

  • Hypar Space
  • Hypar Web App - Visualize, Optimize, Compare
  • Hypar Functions(Excel, Grasshopper, C#, Python)
  • “The Cloud”

Although Hypar can automatically layout the generated result for users, we still have ability to do adjust.

  • select
  • remove

Hexo

I set up my blog with some other bloggers’ help. So I think the first post should be the things about how to write a blog with HEXO.
After walked throught the intallation parts, there’re only 4 commands I need to rememeber, which I might not.

hexo new [postName]
hexo cl
hexo g
hexo s

and also

hexo s

For check the result without deploying them.

Some reference resources:

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

Type of Tests

  • Unit
  • Integration
  • End-to-End

Unit test

Tests a unit of an application without its external dependencies

  • Cheap to write
  • Execute fast
  • Don’t give a lot of confidence

Integration Test

Tests the application with its external dependencies

  • Take longer to execute
  • Give more confidence

End to End Test

Drives an application through its UI

  • Give you the greatest confidence
  • very slow
  • very brittle

Testing Frameworks

  • NUnit
  • MSTest (embed in VisualStudio)
  • xUnit

All of the Testing Frameworks have:

  • Library
  • Test runner

Good pracitce for naming the TestingMetod:
FunctionName_Condition_ExpectReturn

Inside every UnitTest with triple A

  1. Arrange
  2. Act
  3. Assert

Test-driven Development (TDD

  1. write a failing test
  2. Write the simplest code to make the test pass.
  3. Refactor if necessary.

Benefits of TDD

  • Testable Source Code
  • Full Coverage by Tests
  • Simpler Implementation

Reference_GeeksforGeeks
Thread Binary Tree

Inorder Tree Traversal without recursion and without stack

Using Morris Travesal, we can traverse the tree without using stack and recursion. The idea of Morris Traversal is based on Threaded Binary Tree.

In this traveral, we first create links to Inorder successor and print the data using these links, and finally revert the changes to restore original tree.

  1. Initalize current as root
  2. While current is not NULL
    If the current does not have left child
     1. Print current's data
     2. Go to the right, i.e., current = current->right
    
    Else
     Find rightmost node in current left subtree `OR` node whose right child == current
     *If*
         we found right child == current
         Go to the right, i.e. current = current->right
     *Else*
         1. Make current as the right child of that rightmost node we found; and
         2. Go to this left child, i.e., current = current -> current->left
    

Although the tree is modified through the traversal, it is reverted back to its original shape after the completion. No extra space is required

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
struct tNode{
int data;
struct tNode* left;
struct tNode* right;
};

void MorrisTraversal(struct tNode* root){
struct tNode* current;
struct tNode* pre;

if(root == NULL)
return;

current = root;
while(current != NULL){
if(current->left == NULL){
printf("%d", current->data);
current = current->right;
}
else{
// Find the inorder predecessor of current
pre = current->left;
while(pre->right != NULL && pre->right != current)
pre = pre->right;

// Make current as the right child of its inorder predecessor
if(pre->right == NULL){
pre->right = current;
current = current->left;
}

// Revert the changes made in the `if` part to restore the original tree i.e., fix the right child of predecessor
else{
pre->right = NULL;
printf("%d", current->data);
current = current->right;
}
}
}

}


struct tNode* newtNode(int data)
{
struct tNode* node = new tNode;
node->data = data;
node->left = NULL;
node->right = NULL;

return (node);
}

int main()
{

/* Constructed binary tree is
1
/ \
2 3
/ \
4 5
*/
struct tNode* root = newtNode(1);
root->left = newtNode(2);
root->right = newtNode(3);
root->left->left = newtNode(4);
root->left->right = newtNode(5);

MorrisTraversal(root);

return 0;
}

Inorder Tree Traversal without Recursion

Reference

Time Complexity: O(n2)

Using Stack is the obvious way to travese tree without recursion.

  1. create an empty stack S
  2. Initialize current node as root
  3. Push the current node to S and set current = current->left until current is NULL
  4. If current is NULL and stack is not empty then
    1. Pop the top item from stack
    2. Print the popped item, set current = popped_item->right
    3. Go to step 3.
  5. If current is NULL and stack is empty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include<bits/stdc++.h>
using namespace std;

struct Node{
int data;
struct Node* left;
struct Node* right;
Node(int data){
this->data = data;
left = right = null;
}
};

void inOrder(struct Node* root){
stack<Node*> s;
Node* curr = root;
while(curr!= NULL || s.empty()==false){
while(curr!= NULL){
s.push(curr);
curr = curr->left;
}
curr = s.top();
s.pop();
cout<<curr->data<<" ";
curr = curr->right;
}
}

int main(){
struct Node* root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->left->left = new Node(4);
root->left->right = new Node(5);

inOrder(root);
return 0;
}

Breadth-first search

Breath-first search(BFS) is an algorithm for traversing or searching tree or graph data structures. It starts ar the tree root(or some arbitrary node of a graph), and explores all of the neighbor nodes at the present depth prior to moving on to the nodes at the next depth level. -Wiki

Queue Method

Pseudocode


Input: A graph G and a starting vertex root of G
Output: Goal state. THe parent links trace the shortest path back to root.

1
2
3
4
5
6
7
8
9
procedure BFS(G, root) is
let Q be a queue
label root as discovered
Q.enqueue(root)
while Q is not empty do
v := Q.dequeue()
if c is the goal then
return v
for all edges from v to w in G.

The concept can refer to this article, though it is in Japanese.
BFS_queue
LeetCode_BFS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
vector<vector<int>> levelTravese(TreeNode* root){
vector<vector<int>> LvTraverse;
if(root == NULL)
return LvTraverse;

queue<TreeNode*> q;
q.push(root);
TreeNode* node = root;

while(!q.empty()){
int k = q.size();
vector<int> tmp;
while(k--){
root = q.front();
tmp.push_back(root->val);
q.pop();

if(root->left)
q.push(root->left);
if(root->right)
q.push(root->right);
}
LvTraverse.push_back(tmp);

}
return LvTraverse;

}

Recursive Method

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
int height(TreeNode* node){
if(node == NULL)
return 0;
else{
int lheight = height(node->left);
int rheight = height(node->right);
return lheight > rheight ? lheight+1 : rheight+1;
}
}



vector<vector<int>> printlevelOrder(TreeNode* root){
vector<vector<int>> vecs;
for(int i = 1; i<= height(root);i++){
vector<int> invec;
AddGivenLevel(root, i, invec);
vecs.push_back(invec);
}
return vecs;
}


void AddGivenLevel(TreeNode* root, int level, vector<int>& vec){
if(root==NULL)
return;
if(level ==1)
vec.push_back(root->val);
else if(level>1){
AddGivenLevel(root->left, level-1, vec);
AddGivenLevel(root->right, level-1, vec);
}
}

Note:

  1. height can be found recursively. height(1_based) = level(0_based) + 1

Solve Tree Problems Recursively

Can refer to the LeetCode PageLINK

Typically, we can solve a tree problem recursively using a top-down approach or using a bottom-up approach.

Top-down Solution

Top-down means that in each recursive call, we will visit the node first to come up with some values, and pass these values to its children when calling the function recursively.

So the top-down solution can be consideredd as a kind of preorder travesal. To be specific, the recursive function top-down(root, params) works like this:

  1. return specific value for null node
  2. update the answer if needed // answer <— params
  3. left_ans = top_down(root.left, left_params) // left_params <— root.val ,params
  4. right_ans = top_down(root.right, right_params) // right_params <— root.val , params
  5. return the answer if needed // answers <— left_ans, right_ans

For example - find height of a binary Tree

We know that depth of the root node is 1

  1. For each node, if we know its depth, we will know the depth of its children.
  2. Therefore, if we pass the depth of the node as a parameter when calling the function recursively, all the nodes will know their depth.

  1. return if root is NULL
  2. if root is a leaf node:
  3. answer = max(answer, depth)      // update the answer if needed
    
  4. maximum_depth(root.left, depth + 1)
  5. maximum_depth(root.right, depth+ 1)

1
2
3
4
5
6
7
8
9
10
11
int answer;		       // don't forget to initialize answer before call maximum_depth
void maximum_depth(TreeNode* root, int depth) {
if (!root) {
return;
}
if (!root->left && !root->right) {
answer = max(answer, depth);
}
maximum_depth(root->left, depth + 1);
maximum_depth(root->right, depth + 1);
}

Button-up Solution

Button-up is another recursive solution. In each recursive call, we will firstly call the function recursively for all the children nodes and then come up with the answer according to the returned valued and the value of the current node itself. This process can be regraded as a kind of postordered traversal. Typically, a “button-up” recursive function bottom_up(root) will be something like this:

  1. return specific value for null node
  2. left_ans = bottom_up(root.left) // call function recursively for left child
  3. right_ans = bottom_up(root.right) // call function recursively for right child
  4. return answers // answer <– left_ans, right_ans, root.val

For example - find height of a binary Tree

Same exmaple, different perspective.

  1. If we know the maximum depth l of the subtree rooted at its left child and the maximum depth r of the subtree rooted at its right child, can we answer the previous question?

  2. Of course yes, we can choose the maximum between them and add 1 to get the maximum depth of the subtree rooted at the current node. That is x = max(l,r) + 1

  3. return 0 if root is null

  4. left_depth = maximum_depth(root.left)

  5. right_depth = maximum_depth(root.right)

  6. return max(left_depth, right_depth) + 1

1
2
3
4
5
6
7
8
int maximum_depth(TreeNode* root) {
if (!root) {
return 0; // return 0 for null node
}
int left_depth = maximum_depth(root->left);
int right_depth = maximum_depth(root->right);
return max(left_depth, right_depth) + 1; // return depth of the subtree rooted at root
}

What will we Learn in This class?

How to think about shape…

  • mathematically (differential geometry)
  • computationally (geometry processing)

Central Theme: link these two perspectives

What is Differential Geometry?

Language for talking about locel properties of shape

  • How fast are we traveling along a curve?
  • How much does the surface bend at a point?
  • etc

And their connection to global properties of shape

  • so-called “local-global” relationships.

What is Discrete Differential Geometry

Also a language describing local properties of shape

  • infinity no longer allowed
  • No longer talk about derivatives, infinitesimals…
  • Everything expressed in terms of lengths, angles…
  • Surprisinglt little is lost!
  • Faithfully captures many fundamental ideas

How can we get there?

A common “game” is played in DDG to obtain discrete definitions:

  1. Write down several equivalent definitions in the smooth setting
  2. Apply each smooth definition to an object in the discrete setting
  3. Determine which properties are captured by each resulting **inequivalent ** discrete definition.